ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/logger.C
(Generate patch)

Comparing deliantra/server/common/logger.C (file contents):
Revision 1.20 by root, Mon Oct 12 14:00:57 2009 UTC vs.
Revision 1.31 by root, Sat Nov 17 23:40:00 2018 UTC

1/* 1/*
2 * This file is part of Deliantra, the Roguelike Realtime MMORPG. 2 * This file is part of Deliantra, the Roguelike Realtime MMORPG.
3 * 3 *
4 * Copyright (©) 2017,2018 Marc Alexander Lehmann / the Deliantra team
4 * Copyright (©) 2005,2006,2007,2008 Marc Alexander Lehmann / Robin Redeker / the Deliantra team 5 * Copyright (©) 2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5 * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team
6 * Copyright (©) 1992,2007 Frank Tore Johansen
7 * 6 *
8 * Deliantra is free software: you can redistribute it and/or modify it under 7 * Deliantra is free software: you can redistribute it and/or modify it under
9 * the terms of the Affero GNU General Public License as published by the 8 * the terms of the Affero GNU General Public License as published by the
10 * Free Software Foundation, either version 3 of the License, or (at your 9 * Free Software Foundation, either version 3 of the License, or (at your
11 * option) any later version. 10 * option) any later version.
12 * 11 *
13 * This program is distributed in the hope that it will be useful, 12 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details. 15 * GNU General Public License for more details.
17 * 16 *
18 * You should have received a copy of the Affero GNU General Public License 17 * You should have received a copy of the Affero GNU General Public License
19 * and the GNU General Public License along with this program. If not, see 18 * and the GNU General Public License along with this program. If not, see
20 * <http://www.gnu.org/licenses/>. 19 * <http://www.gnu.org/licenses/>.
21 * 20 *
22 * The authors can be reached via e-mail to <support@deliantra.net> 21 * The authors can be reached via e-mail to <support@deliantra.net>
23 */ 22 */
24 23
25#include <cstdarg> 24#include <cstdarg>
26#include <cstring> 25#include <cstring>
40 char *buf; // includes PREFIX_LEN garbage bytes 39 char *buf; // includes PREFIX_LEN garbage bytes
41 int len; 40 int len;
42 int flags; 41 int flags;
43}; 42};
44 43
44typedef std::vector<logline, slice_allocator<logline> > logvector;
45
45static SMUTEX(mutex); 46static SMUTEX(mutex);
47static SMUTEX(fdlock);
46static SCOND(cond); 48static SCOND(cond);
47static int logfd = STDERR_FILENO; 49static int logfd = STDERR_FILENO;
48static int logsync = 1; 50static int logsync = 1;
49static std::vector<logline, slice_allocator<logline> > queue; 51static logvector queue;
50 52
51void set_logfd (int fd) 53int log_setfd (int fd)
52{ 54{
53 SMUTEX_LOCK (mutex); 55 SMUTEX_LOCK (fdlock);
56 int old = logfd;
54 logfd = fd < 0 ? STDERR_FILENO : fd; 57 logfd = fd < 0 ? STDERR_FILENO : fd;
55 SMUTEX_UNLOCK (mutex); 58 SMUTEX_UNLOCK (fdlock);
56}
57 59
60 return old;
61}
62
58#define PREFIX_LEN sizeof ("0000-00-00 00:00:00.0000+") - 1 63#define PREFIX_LEN sizeof ("0000-00-00 00:00:00.0000 L+") - 1
59 64
60static void 65static void
61log_sync (logline &line) 66log_sync (logline &line)
62{ 67{
68 static const char levelchar [16+1] = "EWIDt???????????";
63 struct tm lt; 69 struct tm lt;
64 char pfx [PREFIX_LEN]; 70 char pfx [PREFIX_LEN];
65 71
66 localtime_r (&line.tv.tv_sec, &lt); 72 localtime_r (&line.tv.tv_sec, &lt);
67 73
68 sprintf (pfx, "%04d-%02d-%02d %02d:%02d:%02d.%04d", 74 sprintf (pfx, "%04d-%02d-%02d %02d:%02d:%02d.%04d %c",
69 lt.tm_year + 1900, 75 lt.tm_year + 1900,
70 lt.tm_mon + 1, 76 lt.tm_mon + 1,
71 lt.tm_mday, 77 lt.tm_mday,
72 lt.tm_hour, 78 lt.tm_hour,
73 lt.tm_min, 79 lt.tm_min,
74 lt.tm_sec, 80 lt.tm_sec,
75 (int)(line.tv.tv_usec / 100) 81 (int)(line.tv.tv_usec / 100),
82 levelchar [line.flags & 15]
76 ); 83 );
77 84
78 pfx [PREFIX_LEN - 1] = line.flags & logSync ? '=' : ' '; 85 pfx [PREFIX_LEN - 1] = line.flags & logSync ? '=' : ' ';
79 86
80 struct iovec iov [2]; 87 struct iovec iov [2];
81 88
82 iov [0].iov_base = pfx; 89 iov [0].iov_base = pfx;
83 iov [0].iov_len = PREFIX_LEN; 90 iov [0].iov_len = PREFIX_LEN;
84 91
85 char *buf = line.buf; 92 char *buf = line.buf;
93
94 if (logsync != 2)
95 SMUTEX_LOCK (fdlock);
86 96
87 while (char *end = strchr (buf, '\n')) 97 while (char *end = strchr (buf, '\n'))
88 { 98 {
89 iov [1].iov_base = buf; 99 iov [1].iov_base = buf;
90 iov [1].iov_len = end - buf + 1; 100 iov [1].iov_len = end - buf + 1;
98 if (buf == line.buf + line.len) 108 if (buf == line.buf + line.len)
99 break; 109 break;
100 110
101 pfx [PREFIX_LEN - 1] = '+'; 111 pfx [PREFIX_LEN - 1] = '+';
102 } 112 }
113
114 if (logsync != 2)
115 SMUTEX_UNLOCK (fdlock);
103 116
104 sfree (line.buf, line.len); 117 sfree (line.buf, line.len);
105} 118}
106 119
107static void * 120static void *
123 // this algorithm could result in an ever-increasing vector 136 // this algorithm could result in an ever-increasing vector
124 // size if we log faster than we can write, but if that happens 137 // size if we log faster than we can write, but if that happens
125 // we have bigger problems. 138 // we have bigger problems.
126 if (idx == queue.size ()) 139 if (idx == queue.size ())
127 { 140 {
141 if (idx < 32)
128 queue.clear (); 142 queue.clear ();
143 else
144 logvector ().swap (queue); // free memory, hopefully
145
129 idx = 0; 146 idx = 0;
130 } 147 }
131 148
132 SMUTEX_UNLOCK (mutex); 149 SMUTEX_UNLOCK (mutex);
133 150
137 154
138void 155void
139log_cleanup () 156log_cleanup ()
140{ 157{
141 logsync = 1; 158 logsync = 1;
159 SMUTEX_UNLOCK (fdlock);
142 160
143 for (;;) 161 for (;;)
144 { 162 {
145 int done; 163 int done;
146 164
150 168
151 if (done) 169 if (done)
152 break; 170 break;
153 171
154 usleep (10000); 172 usleep (10000);
173 SMUTEX_LOCK (fdlock);
174 SMUTEX_UNLOCK (fdlock);
155 } 175 }
156} 176}
157 177
158static void 178static void
159af_child () 179af_child ()
160{ 180{
161 logsync = 1; 181 logsync = 2;
162} 182}
163 183
164static struct logthread : thread 184static struct logthread : thread
165{ 185{
166 logthread () 186 logthread ()
170 logsync = 0; 190 logsync = 0;
171 } 191 }
172} logthread; 192} logthread;
173 193
174void 194void
175LOG (int flags, const char *format, ...) 195LOG (int flags, const_utf8_string format, ...)
176{ 196{
177 int level = flags & 15; 197 int level = flags & 15;
178 198
179 if (level > settings.debug) 199 if (level > settings.debug)
180 return; 200 return;
222 SMUTEX_UNLOCK (mutex); 242 SMUTEX_UNLOCK (mutex);
223 SCOND_SIGNAL (cond); 243 SCOND_SIGNAL (cond);
224 } 244 }
225} 245}
226 246
247static int suspended;
248
249void
250log_suspend ()
251{
252 if (!suspended++)
253 {
254 LOG (llevDebug, "logging suspended.");
255 SMUTEX_LOCK (fdlock);
256 }
257}
258
259void
260log_resume ()
261{
262 if (!--suspended)
263 {
264 SMUTEX_UNLOCK (fdlock);
265 LOG (llevDebug, "logging resumed.");
266 }
267}
268

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines