Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | 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         4. Derivative works are permitted, but they must carry this notice
00027            in full and credit the original source.
00028 
00029 
00030                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00031 
00032       
00033         @version        Initial version, May 2004
00034         @author         Kris
00035                         Anders F Bjorklund (Darwin patches)
00036 
00037 
00038 *******************************************************************************/
00039 
00040 module mango.log.Event;
00041 
00042 version = UseEventFreeList;
00043 
00044 private import  mango.sys.OS;
00045 
00046 private import  mango.log.Hierarchy;
00047 
00048 private import  mango.log.model.ILevel;
00049 
00050 version (Win32)
00051 {
00052         extern(Windows) int QueryPerformanceCounter(ulong *count);
00053         extern(Windows) int QueryPerformanceFrequency(ulong *frequency);
00054 }
00055 
00056 
00057 /*******************************************************************************
00058 
00059         Contains all information about a logging event, and is passed around
00060         between methods once it has been determined that the invoking logger
00061         is enabled for output.
00062 
00063         Note that Event instances are maintained in a freelist rather than
00064         being allocated each time, and they include a scratchpad area for
00065         Layout formatters to use.
00066 
00067 *******************************************************************************/
00068 
00069 public class Event : ILevel
00070 {
00071         // primary event attributes
00072         private char[]          msg,
00073                                 name;
00074         private ulong           time;
00075         private Level           level;
00076         private Hierarchy       hierarchy;
00077 
00078         // timestamps
00079         private static ulong    epochTime;
00080         private static ulong    beginTime;
00081 
00082         // scratch buffer for constructing output strings
00083         struct  Scratch
00084                 {
00085                 uint            length;
00086                 char[256]       content;
00087                 }
00088         package Scratch         scratch;
00089 
00090 
00091         // logging-level names
00092         package static char[][] LevelNames = 
00093         [
00094                 "TRACE ", "INFO ", "WARN ", "ERROR ", "FATAL ", "NONE "
00095         ];
00096 
00097         version (Win32)
00098         {
00099                 private static uint frequency;
00100         }
00101 
00102         version (UseEventFreeList)
00103         {
00104                 /***************************************************************
00105 
00106                         Instance variables for free-list support
00107 
00108                 ***************************************************************/
00109 
00110                 private Event           next;   
00111                 private static Event    freelist;
00112 
00113                 /***************************************************************
00114 
00115                         Allocate an Event from a list rather than 
00116                         creating a new one
00117 
00118                 ***************************************************************/
00119 
00120                 static final synchronized Event allocate ()
00121                 {       
00122                         Event e;
00123 
00124                         if (freelist)
00125                            {
00126                            e = freelist;
00127                            freelist = e.next;
00128                            }
00129                         else
00130                            e = new Event ();                                
00131                         return e;
00132                 }
00133 
00134                 /***************************************************************
00135 
00136                         Return this Event to the free-list
00137 
00138                 ***************************************************************/
00139 
00140                 static final synchronized void deallocate (Event e)
00141                 { 
00142                         e.next = freelist;
00143                         freelist = e;
00144 
00145                         version (EventReset)
00146                                  e.reset();
00147                 }
00148         }
00149 
00150         /***********************************************************************
00151                 
00152                 Setup the timing information for later use. Note how much 
00153                 effort it takes to get epoch time in Win32 ...
00154 
00155         ***********************************************************************/
00156 
00157         static this ()
00158         {
00159                 version (Posix)       
00160                 {
00161                         timeval tv;
00162 
00163                         if (gettimeofday (&tv, null))
00164                             throw new Exception ("high-resolution timer is not available");
00165                         
00166                         epochTime = 1000L * tv.tv_sec;
00167                         beginTime = epochTime + tv.tv_usec / 1000;
00168                 }
00169 
00170                 version (Win32)
00171                 {
00172                         ulong           time;
00173                         ulong           freq;
00174 
00175                         if (! QueryPerformanceFrequency (&freq))
00176                               throw new Exception ("high-resolution timer is not available");
00177                                
00178                         frequency = freq / 1000;
00179                         QueryPerformanceCounter (&time);
00180                         beginTime = time / frequency;
00181 
00182                         SYSTEMTIME      sTime;
00183                         FILETIME        fTime;
00184 
00185                         GetSystemTime (&sTime);
00186                         SystemTimeToFileTime (&sTime, &fTime);
00187                         
00188                         ulong time1 = (cast(long) fTime.dwHighDateTime) << 32 | 
00189                                                   fTime.dwLowDateTime;
00190 
00191                         // first second of 1970 ...
00192                         sTime.wYear = 1970;
00193                         sTime.wMonth = 1;
00194                         sTime.wDayOfWeek = 0;
00195                         sTime.wDay = 1;
00196                         sTime.wHour = 0;
00197                         sTime.wMinute = 0;
00198                         sTime.wSecond = 0;
00199                         sTime.wMilliseconds = 0;
00200                         SystemTimeToFileTime (&sTime, &fTime);
00201 
00202                         ulong time2 = (cast(long) fTime.dwHighDateTime) << 32 | 
00203                                                   fTime.dwLowDateTime;
00204                         
00205                         epochTime = (time1 - time2) / 10_000;
00206                 }
00207         }
00208 
00209         /***********************************************************************
00210                 
00211                 Return the number of milliseconds since the executable
00212                 was started.
00213 
00214         ***********************************************************************/
00215 
00216         final static ulong getRuntime ()
00217         {
00218                 version (Posix)       
00219                 {
00220                         timeval tv;
00221 
00222                         gettimeofday (&tv, null);
00223                         return ((cast(ulong) tv.tv_sec) * 1000 + tv.tv_usec / 1000) - beginTime;
00224                 }
00225 
00226                 version (Win32)
00227                 {
00228                         ulong time;
00229 
00230                         QueryPerformanceCounter (&time);
00231                         return (time / frequency) - beginTime;
00232                 }
00233         }
00234 
00235         /***********************************************************************
00236                 
00237                 Set the various attributes of this event.
00238 
00239         ***********************************************************************/
00240 
00241         final void set (Hierarchy hierarchy, Level level, char[] msg, char[] name)
00242         {
00243                 this.hierarchy = hierarchy;
00244                 this.time = getRuntime ();
00245                 this.level = level;
00246                 this.name = name;
00247                 this.msg = msg;
00248         }
00249 
00250         version (EventReset)
00251         {
00252                 /***************************************************************
00253 
00254                         Reset this event
00255 
00256                 ***************************************************************/
00257 
00258                 final void reset ()
00259                 {
00260                         time = 0;
00261                         msg = null;
00262                         name = null;
00263                         level = Level.None;
00264                 }
00265         }
00266 
00267         /***********************************************************************
00268                 
00269                 Return the message attached to this event.
00270 
00271         ***********************************************************************/
00272 
00273         final override char[] toString ()
00274         {
00275                 return msg;
00276         }
00277 
00278         /***********************************************************************
00279                 
00280                 Return the name of the logger which produced this event
00281 
00282         ***********************************************************************/
00283 
00284         final char[] getName ()
00285         {
00286                 return name;
00287         }
00288 
00289         /***********************************************************************
00290                 
00291                 Return the scratch buffer for formatting. This is a thread
00292                 safe place to format data within, without allocating any
00293                 memory.
00294 
00295         ***********************************************************************/
00296 
00297         final char[] getContent ()
00298         {
00299                 return scratch.content [0..scratch.length];
00300         }
00301 
00302         /***********************************************************************
00303                 
00304                 Return the logger level of this event.
00305 
00306         ***********************************************************************/
00307 
00308         final Level getLevel ()
00309         {
00310                 return level;
00311         }
00312 
00313         /***********************************************************************
00314                 
00315                 Return the logger level name of this event.
00316 
00317         ***********************************************************************/
00318 
00319         final char[] getLevelName ()
00320         {
00321                 return LevelNames[level];
00322         }
00323 
00324         /***********************************************************************
00325                 
00326                 Return the hierarchy where the event was produced from
00327 
00328         ***********************************************************************/
00329 
00330         final Hierarchy getHierarchy ()
00331         {
00332                 return hierarchy;
00333         }
00334 
00335         /***********************************************************************
00336                 
00337                 Return the time this event was produced, relative to the 
00338                 start of this executable
00339 
00340         ***********************************************************************/
00341 
00342         final long getTime ()
00343         {
00344                 return time;
00345         }
00346 
00347         /***********************************************************************
00348                
00349                 Return the time this event was produced, relative to 
00350                 Jan 1st 1970
00351 
00352         ***********************************************************************/
00353 
00354         final ulong getEpochTime ()
00355         {
00356                 return time + epochTime;
00357         }
00358 
00359         /***********************************************************************
00360 
00361                 Append some content to the scratch buffer. This is limited
00362                 to the size of said buffer, and will not expand further.
00363 
00364         ***********************************************************************/
00365 
00366         final Event append (char[] x)
00367         {
00368                 uint addition = x.length;
00369                 uint newLength = scratch.length + x.length;
00370 
00371                 if (newLength < scratch.content.length)
00372                    {
00373                    scratch.content [scratch.length..newLength] = x[0..addition];
00374                    scratch.length = newLength;
00375                    }
00376                 return this;
00377         }
00378 }

Generated on Mon Nov 14 10:59:37 2005 for Mango by  doxygen 1.4.0