3 * - By John Hodge (thePowersGang)
5 * logging.c - Kernel Logging Service
9 #define PRINT_ON_APPEND 1
10 #define USE_RING_BUFFER 1
11 #define RING_BUFFER_SIZE 4096
26 const char *csaLevelColours[] = {
27 "\x1B[35m", "\x1B[34m", "\x1B[36m", "\x1B[31m",
28 "\x1B[33m", "\x1B[32m", "\x1B[0m", "\x1B[0m"
30 const char *csaLevelCodes[] = {"k","p","f","e","w","n","l","d"};
33 typedef struct sLogEntry
35 struct sLogEntry *Next;
36 struct sLogEntry *LevelNext;
43 typedef struct sLogList
50 void Log_AddEvent(char *Ident, int Level, char *Format, va_list Args);
51 static void Log_Int_PrintMessage(tLogEntry *Entry);
52 void Log_KernelPanic(char *Ident, char *Message, ...);
53 void Log_Panic(char *Ident, char *Message, ...);
54 void Log_Error(char *Ident, char *Message, ...);
55 void Log_Warning(char *Ident, char *Message, ...);
56 void Log_Notice(char *Ident, char *Message, ...);
57 void Log_Log(char *Ident, char *Message, ...);
58 void Log_Debug(char *Ident, char *Message, ...);
69 tShortSpinlock glLogOutput;
71 Uint8 gaLog_RingBufferData[sizeof(tRingBuffer)+RING_BUFFER_SIZE];
72 tRingBuffer *gpLog_RingBuffer = (void*)gaLog_RingBufferData;
76 tLogList gLog_Levels[NUM_LOG_LEVELS];
81 * \brief Adds an event to the log
83 void Log_AddEvent(char *Ident, int Level, char *Format, va_list Args)
89 if( Level >= NUM_LOG_LEVELS ) return;
91 va_copy(args_tmp, Args);
92 len = vsnprintf(NULL, 256, Format, args_tmp);
94 //Log("len = %i", len);
98 char buf[sizeof(tLogEntry)+len+1];
101 ent = malloc(sizeof(tLogEntry)+len+1);
104 strncpy(ent->Ident, Ident, 8);
105 ent->Ident[8] = '\0';
108 vsnprintf( ent->Data, len+1, Format, Args );
112 #define LOG_HDR_LEN (14+1+2+8+2)
113 char newData[ LOG_HDR_LEN + len + 2 + 1 ];
114 sprintf( newData, "%014lli%s [%+8s] ",
115 ent->Time, csaLevelCodes[Level], Ident);
116 strcpy( newData + LOG_HDR_LEN, ent->Data );
117 strcpy( newData + LOG_HDR_LEN + len, "\r\n" );
118 gpLog_RingBuffer->Space = RING_BUFFER_SIZE; // Needed to init the buffer
119 RingBuffer_Write( gpLog_RingBuffer, newData, LOG_HDR_LEN + len + 2 );
122 Mutex_Acquire( &glLog );
124 ent->Next = gLog.Tail;
128 gLog.Tail = gLog.Head = ent;
130 ent->LevelNext = gLog_Levels[Level].Tail;
131 if(gLog_Levels[Level].Head)
132 gLog_Levels[Level].Tail = ent;
134 gLog_Levels[Level].Tail = gLog_Levels[Level].Head = ent;
136 Mutex_Release( &glLog );
140 Log_Int_PrintMessage( ent );
149 * \brief Prints a log message to the debug console
151 void Log_Int_PrintMessage(tLogEntry *Entry)
153 SHORTLOCK( &glLogOutput );
154 LogF("%s%014lli%s [%+8s] %s\x1B[0m\r\n",
155 csaLevelColours[Entry->Level],
157 csaLevelCodes[Entry->Level],
161 SHORTREL( &glLogOutput );
165 * \brief KERNEL PANIC!!!!
167 void Log_KernelPanic(char *Ident, char *Message, ...)
170 va_start(args, Message);
171 Log_AddEvent(Ident, LOG_LEVEL_KPANIC, Message, args);
176 * \brief Panic Message - Driver Unrecoverable error
178 void Log_Panic(char *Ident, char *Message, ...)
181 va_start(args, Message);
182 Log_AddEvent(Ident, LOG_LEVEL_PANIC, Message, args);
187 * \brief Error Message - Recoverable Error
189 void Log_Error(char *Ident, char *Message, ...)
192 va_start(args, Message);
193 Log_AddEvent(Ident, LOG_LEVEL_ERROR, Message, args);
198 * \brief Warning Message - Something the user should know
200 void Log_Warning(char *Ident, char *Message, ...)
204 va_start(args, Message);
205 Log_AddEvent(Ident, LOG_LEVEL_WARNING, Message, args);
210 * \brief Notice Message - Something the user might like to know
212 void Log_Notice(char *Ident, char *Message, ...)
215 va_start(args, Message);
216 Log_AddEvent(Ident, LOG_LEVEL_NOTICE, Message, args);
221 * \brief Log Message - Possibly useful information
223 void Log_Log(char *Ident, char *Message, ...)
226 va_start(args, Message);
227 Log_AddEvent(Ident, LOG_LEVEL_LOG, Message, args);
232 * \brief Debug Message - Only a developer would want this info
234 void Log_Debug(char *Ident, char *Message, ...)
237 va_start(args, Message);
238 Log_AddEvent(Ident, LOG_LEVEL_DEBUG, Message, args);