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