3 * - By John Hodge (thePowersGang)
5 * logging.c - Kernel Logging Service
10 #define CACHE_MESSAGES 0
11 #define PRINT_ON_APPEND 1
12 #define USE_RING_BUFFER 1
13 #define RING_BUFFER_SIZE 4096
28 const char *csaLevelColours[] = {
29 "\x1B[35m", "\x1B[34m", "\x1B[36m", "\x1B[31m",
30 "\x1B[33m", "\x1B[32m", "\x1B[0m", "\x1B[0m"
32 const char *csaLevelCodes[] = {"k","p","f","e","w","n","l","d"};
35 typedef struct sLogEntry
37 struct sLogEntry *Next;
38 struct sLogEntry *LevelNext;
45 typedef struct sLogList
52 void Log_AddEvent(const char *Ident, int Level, const char *Format, va_list Args);
53 static void Log_Int_PrintMessage(tLogEntry *Entry);
54 //void Log_KernelPanic(const char *Ident, const char *Message, ...);
55 //void Log_Panic(const char *Ident, const char *Message, ...);
56 //void Log_Error(const char *Ident, const char *Message, ...);
57 //void Log_Warning(const char *Ident, const char *Message, ...);
58 //void Log_Notice(const char *Ident, const char *Message, ...);
59 //void Log_Log(const char *Ident, const char *Message, ...);
60 //void Log_Debug(const char *Ident, const char *Message, ...);
71 tShortSpinlock glLogOutput;
74 Uint8 gaLog_RingBufferData[sizeof(tRingBuffer)+RING_BUFFER_SIZE];
75 tRingBuffer *gpLog_RingBuffer = (void*)gaLog_RingBufferData;
79 tLogList gLog_Levels[NUM_LOG_LEVELS];
80 # endif // USE_RING_BUFFER
81 #endif // CACHE_MESSAGES
85 * \brief Adds an event to the log
87 void Log_AddEvent(const char *Ident, int Level, const char *Format, va_list Args)
93 if( Level >= NUM_LOG_LEVELS ) return;
95 va_copy(args_tmp, Args);
96 len = vsnprintf(NULL, 0, Format, args_tmp);
98 #if USE_RING_BUFFER || !CACHE_MESSAGES
100 char buf[sizeof(tLogEntry)+len+1];
103 ent = malloc(sizeof(tLogEntry)+len+1);
106 strncpy(ent->Ident, Ident, 8);
107 ent->Ident[8] = '\0';
110 vsnprintf( ent->Data, len+1, Format, Args );
115 #define LOG_HDR_LEN (14+1+2+8+2)
116 char newData[ LOG_HDR_LEN + len + 2 + 1 ];
117 sprintf( newData, "%014lli%s [%-8.8s] ",
118 ent->Time, csaLevelCodes[Level], Ident);
119 strcpy( newData + LOG_HDR_LEN, ent->Data );
120 strcpy( newData + LOG_HDR_LEN + len, "\r\n" );
121 gpLog_RingBuffer->Space = RING_BUFFER_SIZE; // Needed to init the buffer
122 RingBuffer_Write( gpLog_RingBuffer, newData, LOG_HDR_LEN + len + 2 );
125 Mutex_Acquire( &glLog );
127 ent->Next = gLog.Tail;
128 tLogEntry **pnp = (gLog.Tail ? &gLog.Tail->Next : &gLog.Head);
132 ent->LevelNext = gLog_Levels[Level].Tail;
133 pnp = (gLog_Levels[Level].Tail ? &gLog_Levels[Level].Tail->LevelNext : &gLog_Levels[Level].Head);
135 gLog_Levels[Level].Tail = ent;
137 Mutex_Release( &glLog );
141 #if PRINT_ON_APPEND || !CACHE_MESSAGES
142 Log_Int_PrintMessage( ent );
145 #if USE_RING_BUFFER || !CACHE_MESSAGES
151 * \brief Prints a log message to the debug console
153 void Log_Int_PrintMessage(tLogEntry *Entry)
155 if( CPU_HAS_LOCK(&glLogOutput) )
156 return ; // TODO: Error?
157 SHORTLOCK( &glLogOutput );
159 csaLevelColours[Entry->Level],
162 LogF("%s [%-8s] %i - %.*s",
163 csaLevelCodes[Entry->Level],
169 LogF("\x1B[0m\r\n"); // Separate in case Entry->Data is too long
170 SHORTREL( &glLogOutput );
174 * \brief KERNEL PANIC!!!!
176 void Log_KernelPanic(const char *Ident, const char *Message, ...)
179 va_start(args, Message);
180 Log_AddEvent(Ident, LOG_LEVEL_KPANIC, Message, args);
182 Panic("Log_KernelPanic - %s", Ident);
186 * \brief Panic Message - Driver Unrecoverable error
188 void Log_Panic(const char *Ident, const char *Message, ...)
191 va_start(args, Message);
192 Log_AddEvent(Ident, LOG_LEVEL_PANIC, Message, args);
197 * \brief Error Message - Recoverable Error
199 void Log_Error(const char *Ident, const char *Message, ...)
202 va_start(args, Message);
203 Log_AddEvent(Ident, LOG_LEVEL_ERROR, Message, args);
208 * \brief Warning Message - Something the user should know
210 void Log_Warning(const char *Ident, const char *Message, ...)
214 va_start(args, Message);
215 Log_AddEvent(Ident, LOG_LEVEL_WARNING, Message, args);
220 * \brief Notice Message - Something the user might like to know
222 void Log_Notice(const char *Ident, const char *Message, ...)
225 va_start(args, Message);
226 Log_AddEvent(Ident, LOG_LEVEL_NOTICE, Message, args);
231 * \brief Log Message - Possibly useful information
233 void Log_Log(const char *Ident, const char *Message, ...)
236 va_start(args, Message);
237 Log_AddEvent(Ident, LOG_LEVEL_LOG, Message, args);
242 * \brief Debug Message - Only a developer would want this info
244 void Log_Debug(const char *Ident, const char *Message, ...)
247 va_start(args, Message);
248 Log_AddEvent(Ident, LOG_LEVEL_DEBUG, Message, args);