00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 module mango.log.Event;
00041
00042 version = UseEventFreeList;
00043
00044 private import mango.log.Hierarchy;
00045
00046 private import mango.log.model.ILevel;
00047
00048
00049
00050
00051
00052
00053
00054 version (Win32)
00055 {
00056 private import std.c.windows.windows;
00057
00058 extern(Windows) int QueryPerformanceCounter(ulong *count);
00059 extern(Windows) int QueryPerformanceFrequency(ulong *frequency);
00060 }
00061
00062 version (Posix)
00063 {
00064 version (linux)
00065 private import std.c.linux.linux;
00066
00067 version (darwin)
00068 private import std.c.darwin.darwin;
00069 }
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083 public class Event : ILevel
00084 {
00085 struct Scratch
00086 {
00087 uint length;
00088 char[256] content;
00089 }
00090
00091 package Scratch scratch;
00092 private char[] msg,
00093 name;
00094 private ulong time;
00095 private Level level;
00096 private Hierarchy hierarchy;
00097
00098 private static uint epochTime;
00099 private static ulong beginTime;
00100
00101 version (Win32)
00102 {
00103 private static uint frequency;
00104 }
00105
00106 version (UseEventFreeList)
00107 {
00108
00109
00110
00111
00112
00113
00114 private Event next;
00115 private static Event freelist;
00116
00117
00118
00119
00120
00121
00122
00123
00124 static final synchronized Event allocate ()
00125 {
00126 Event e;
00127
00128 if (freelist)
00129 {
00130 e = freelist;
00131 freelist = e.next;
00132 }
00133 else
00134 e = new Event ();
00135 return e;
00136 }
00137
00138
00139
00140
00141
00142
00143
00144 static final synchronized void deallocate (Event e)
00145 {
00146 e.next = freelist;
00147 freelist = e;
00148
00149 version (EventReset)
00150 e.reset();
00151 }
00152 }
00153
00154
00155
00156
00157
00158
00159
00160
00161 static this ()
00162 {
00163 version (Posix)
00164 {
00165 timeval tv;
00166
00167 if (gettimeofday (&tv, null))
00168 throw new Exception ("high-resolution timer is not available");
00169
00170 epochTime = tv.tv_sec;
00171 beginTime = (cast(ulong) tv.tv_sec) * 1000 + tv.tv_usec / 1000;
00172 }
00173
00174 version (Win32)
00175 {
00176 ulong time;
00177 ulong freq;
00178
00179 if (! QueryPerformanceFrequency (&freq))
00180 throw new Exception ("high-resolution timer is not available");
00181
00182 frequency = freq / 1000;
00183 QueryPerformanceCounter (&time);
00184 beginTime = time / frequency;
00185
00186 SYSTEMTIME sTime;
00187 FILETIME fTime;
00188
00189 GetSystemTime (&sTime);
00190 SystemTimeToFileTime (&sTime, &fTime);
00191
00192 ulong time1 = (cast(long) fTime.dwHighDateTime) << 32 |
00193 fTime.dwLowDateTime;
00194
00195
00196 sTime.wYear = 1969;
00197 sTime.wMonth = 12;
00198 sTime.wDayOfWeek = 3;
00199 sTime.wDay = 31;
00200 sTime.wHour = 23;
00201 sTime.wMinute = 0;
00202 sTime.wSecond = 0;
00203 sTime.wMilliseconds = 0;
00204 SystemTimeToFileTime (&sTime, &fTime);
00205
00206 ulong time2 = (cast(long) fTime.dwHighDateTime) << 32 |
00207 fTime.dwLowDateTime;
00208
00209 epochTime = (time1 - time2) / 10_000_000;
00210 }
00211 }
00212
00213
00214
00215
00216
00217
00218
00219
00220 final static ulong getUptime ()
00221 {
00222 version (Posix)
00223 {
00224 timeval tv;
00225
00226 gettimeofday (&tv, null);
00227 return ((cast(ulong) tv.tv_sec) * 1000 + tv.tv_usec / 1000) - beginTime;
00228 }
00229
00230 version (Win32)
00231 {
00232 ulong time;
00233
00234 QueryPerformanceCounter (&time);
00235 return (time / frequency) - beginTime;
00236 }
00237 }
00238
00239
00240
00241
00242
00243
00244
00245 final void set (Hierarchy hierarchy, Level level, char[] msg, char[] name)
00246 {
00247 this.hierarchy = hierarchy;
00248 this.time = getUptime ();
00249 this.level = level;
00250 this.name = name;
00251 this.msg = msg;
00252 }
00253
00254 version (EventReset)
00255 {
00256
00257
00258
00259
00260
00261
00262 final void reset ()
00263 {
00264 time = 0;
00265 msg = null;
00266 name = null;
00267 level = Level.None;
00268 }
00269 }
00270
00271
00272
00273
00274
00275
00276
00277 final override char[] toString ()
00278 {
00279 return msg;
00280 }
00281
00282
00283
00284
00285
00286
00287
00288 final char[] getName ()
00289 {
00290 return name;
00291 }
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301 final char[] getContent ()
00302 {
00303 return scratch.content [0..scratch.length];
00304 }
00305
00306
00307
00308
00309
00310
00311
00312 final Level getLevel ()
00313 {
00314 return level;
00315 }
00316
00317
00318
00319
00320
00321
00322
00323 final Hierarchy getHierarchy ()
00324 {
00325 return hierarchy;
00326 }
00327
00328
00329
00330
00331
00332
00333
00334 final long getTime ()
00335 {
00336 return time;
00337 }
00338
00339
00340
00341
00342
00343
00344
00345 final uint getEpochSeconds ()
00346 {
00347 return (time / 1000) + epochTime;
00348 }
00349
00350
00351
00352
00353
00354
00355
00356 final ulong getEpochMilliSeconds ()
00357 {
00358 return time + (cast(ulong) epochTime) * 1000;
00359 }
00360
00361
00362
00363
00364
00365
00366
00367 final uint getMilliSeconds ()
00368 {
00369 return time % 1000;
00370 }
00371
00372
00373
00374
00375
00376
00377
00378
00379 final Event append (char[] x)
00380 {
00381 uint addition = x.length;
00382 uint newLength = scratch.length + x.length;
00383
00384 if (newLength < scratch.content.length)
00385 {
00386 scratch.content [scratch.length..newLength] = x[0..addition];
00387 scratch.length = newLength;
00388 }
00389 return this;
00390 }
00391 }