Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members | Related Pages

Event.d

Go to the documentation of this file.
00001 /*******************************************************************************
00002 
00003         @file Event.d
00004 
00005         Copyright (C) 2004 Kris Bell
00006         
00007         This software is provided 'as-is', without any express or implied
00008         warranty. In no event will the authors be held liable for damages
00009         of any kind arising from the use of this software.
00010         
00011         Permission is hereby granted to anyone to use this software for any 
00012         purpose, including commercial applications, and to alter it and/or 
00013         redistribute it freely, subject to the following restrictions:
00014         
00015         1. The origin of this software must not be misrepresented; you must 
00016            not claim that you wrote the original software. If you use this 
00017            software in a product, an acknowledgment within documentation of 
00018            said product would be appreciated but is not required.
00019 
00020         2. Altered source versions must be plainly marked as such, and must 
00021            not be misrepresented as being the original software.
00022 
00023         3. This notice may not be removed or altered from any distribution
00024            of the source.
00025 
00026 
00027                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00028 
00029       
00030         @version        Initial version, May 2004
00031         @author         Kris
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         Haul in additional O/S specific imports
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         Contains all information about a logging event, and is passed around
00066         between methods once it has been determined that the invoking logger
00067         is enabled for output.
00068 
00069         Note that Event instances are maintained in a freelist rather than
00070         being allocated each time, and they include a scratchpad area for
00071         Layout formatters to use.
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                         Instance variables for free-list support
00097 
00098                 ***************************************************************/
00099 
00100                 private Event           next;   
00101                 private static Event    freelist;
00102 
00103                 /***************************************************************
00104 
00105                         Allocate an Event from a list rather than 
00106                         creating a new one
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                         Return this Event to the free-list
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                 Setup the timing information for later use. Note how much 
00143                 effort it takes to get epoch time in Win32 ...
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                         // first second of 1970 ...
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                 Return the number of milliseconds since the executable
00202                 was started.
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                 Set the various attributes of this event.
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                         Reset this event
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                 Return the message attached to this event.
00260 
00261         ***********************************************************************/
00262 
00263         final override char[] toString ()
00264         {
00265                 return msg;
00266         }
00267 
00268         /***********************************************************************
00269                 
00270                 Return the name of the logger which produced this event
00271 
00272         ***********************************************************************/
00273 
00274         final char[] getName ()
00275         {
00276                 return name;
00277         }
00278 
00279         /***********************************************************************
00280                 
00281                 Return the scratch buffer for formatting. This is a thread
00282                 safe place to format data within, without allocating any
00283                 memory.
00284 
00285         ***********************************************************************/
00286 
00287         final char[] getScratch ()
00288         {
00289                 return scratch;
00290         }
00291 
00292         /***********************************************************************
00293                 
00294                 Return the logger level of this event.
00295 
00296         ***********************************************************************/
00297 
00298         final Level getLevel ()
00299         {
00300                 return level;
00301         }
00302 
00303         /***********************************************************************
00304                 
00305                 Return the hierarchy where the event was produced from
00306 
00307         ***********************************************************************/
00308 
00309         final Hierarchy getHierarchy ()
00310         {
00311                 return hierarchy;
00312         }
00313 
00314         /***********************************************************************
00315                 
00316                 Return the time this event was produced
00317 
00318         ***********************************************************************/
00319 
00320         final long getTime ()
00321         {
00322                 return time;
00323         }
00324 
00325         /***********************************************************************
00326                 
00327                 Return the number of seconds since Jan 1st 1970
00328 
00329         ***********************************************************************/
00330 
00331         final uint getEpochSeconds ()
00332         {
00333                 return (time / 1000) + epochTime;
00334         }
00335 
00336         /***********************************************************************
00337                
00338                 Return the number of milliseconds since Jan 1st 1970
00339 
00340         ***********************************************************************/
00341 
00342         final ulong getEpochMilliSeconds ()
00343         {
00344                 return time + (cast(ulong) epochTime) * 1000;
00345         }
00346 
00347         /***********************************************************************
00348 
00349                 Isolate the millisecond portion of the event timestamp
00350 
00351         ***********************************************************************/
00352 
00353         final uint getMilliSeconds ()
00354         {
00355                 return time % 1000;
00356         }
00357 }

Generated on Sun Nov 7 19:06:50 2004 for Mango by doxygen 1.3.6