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