Many changes, bugfixes to user vsnprintf and to escape code handling
[tpg/acess2.git] / Kernel / logging.c
1 /*
2  * Acess 2 Kernel
3  * - By John Hodge (thePowersGang)
4  *
5  * logging.c - Kernel Logging Service
6  */
7 #include <acess.h>
8
9 #define PRINT_ON_APPEND 1
10
11 // === CONSTANTS ===
12 enum eLogLevels
13 {
14         LOG_LEVEL_KPANIC,
15         LOG_LEVEL_PANIC,
16         LOG_LEVEL_FATAL,
17         LOG_LEVEL_ERROR,
18         LOG_LEVEL_WARNING,
19         LOG_LEVEL_NOTICE,
20         LOG_LEVEL_LOG,
21         LOG_LEVEL_DEBUG,
22         NUM_LOG_LEVELS
23 };
24 const char      *csaLevelColours[] = {
25                 "\x1B[35m", "\x1B[34m", "\x1B[36m", "\x1B[31m",
26                 "\x1B[33m", "\x1B[32m", "\x1B[0m", "\x1B[0m"
27                 };
28 const char      *csaLevelCodes[] =  {"k","p","f","e","w","n","l","d"};
29
30 // === TYPES ===
31 typedef struct sLogEntry
32 {
33         struct sLogEntry        *Next;
34         struct sLogEntry        *LevelNext;
35         Sint64  Time;
36          int    Level;
37          int    Length;
38         char    Ident[9];
39         char    Data[];
40 }       tLogEntry;
41 typedef struct sLogList
42 {
43         tLogEntry       *Head;
44         tLogEntry       *Tail;
45 }       tLogList;
46
47 // === PROTOTYPES ===
48 void    Log_AddEvent(char *Ident, int Level, char *Format, va_list Args);
49 static void     Log_Int_PrintMessage(tLogEntry *Entry);
50 void    Log_KernelPanic(char *Ident, char *Message, ...);
51 void    Log_Panic(char *Ident, char *Message, ...);
52 void    Log_Error(char *Ident, char *Message, ...);
53 void    Log_Warning(char *Ident, char *Message, ...);
54 void    Log_Notice(char *Ident, char *Message, ...);
55 void    Log_Log(char *Ident, char *Message, ...);
56 void    Log_Debug(char *Ident, char *Message, ...);
57 //static Uint64 Log_Int_GetIdent(const char *Str);
58
59 // === EXPORTS ===
60 EXPORT(Log_KernelPanic);
61 EXPORT(Log_Panic);
62 EXPORT(Log_Error);
63 EXPORT(Log_Warning);
64 EXPORT(Log_Notice);
65 EXPORT(Log_Log);
66 EXPORT(Log_Debug);
67
68 // === GLOBALS ===
69 tSpinlock       glLog;
70 tLogList        gLog;
71 tLogList        gLog_Levels[NUM_LOG_LEVELS];
72
73 // === CODE ===
74 /**
75  * \brief Adds an event to the log
76  */
77 void Log_AddEvent(char *Ident, int Level, char *Format, va_list Args)
78 {
79          int    len;
80         tLogEntry       *ent;
81         
82         if( Level >= NUM_LOG_LEVELS )   return;
83         
84         len = vsnprintf(NULL, 256, Format, Args);
85         
86         //Log("len = %i", len);
87         
88         ent = malloc(sizeof(tLogEntry)+len+1);
89         ent->Time = now();
90         strncpy(ent->Ident, Ident, 8);
91         ent->Level = Level;
92         ent->Length = len;
93         vsnprintf( ent->Data, 256, Format, Args );
94         
95         //Log("ent->Ident = '%s'", ent->Ident);
96         //Log("ent->Data = '%s'", ent->Data);
97         
98         LOCK( &glLog );
99         
100         ent->Next = gLog.Tail;
101         if(gLog.Head)
102                 gLog.Tail = ent;
103         else
104                 gLog.Tail = gLog.Head = ent;
105         
106         ent->LevelNext = gLog_Levels[Level].Tail;
107         if(gLog_Levels[Level].Head)
108                 gLog_Levels[Level].Tail = ent;
109         else
110                 gLog_Levels[Level].Tail = gLog_Levels[Level].Head = ent;
111         
112         RELEASE( &glLog );
113         
114         #if PRINT_ON_APPEND
115         Log_Int_PrintMessage( ent );
116         #endif
117         
118 }
119
120 /**
121  * \brief Prints a log message to the debug console
122  */
123 void Log_Int_PrintMessage(tLogEntry *Entry)
124 {
125         LogF("%s%018lli%s [%+8s] %s\x1B[0m\n",
126                 csaLevelColours[Entry->Level],
127                 Entry->Time,
128                 csaLevelCodes[Entry->Level],
129                 Entry->Ident,
130                 Entry->Data
131                 );
132 }
133
134 /**
135  * \brief KERNEL PANIC!!!!
136  */
137 void Log_KernelPanic(char *Ident, char *Message, ...)
138 {
139         va_list args;   
140         va_start(args, Message);
141         Log_AddEvent(Ident, LOG_LEVEL_KPANIC, Message, args);
142         va_end(args);
143 }
144
145 /**
146  * \brief Panic Message - Driver Unrecoverable error
147  */
148 void Log_Panic(char *Ident, char *Message, ...)
149 {
150         va_list args;   
151         va_start(args, Message);
152         Log_AddEvent(Ident, LOG_LEVEL_PANIC, Message, args);
153         va_end(args);
154 }
155
156 /**
157  * \brief Error Message - Recoverable Error
158  */
159 void Log_Error(char *Ident, char *Message, ...)
160 {
161         va_list args;   
162         va_start(args, Message);
163         Log_AddEvent(Ident, LOG_LEVEL_ERROR, Message, args);
164         va_end(args);
165 }
166
167 /**
168  * \brief Warning Message - Something the user should know
169  */
170 void Log_Warning(char *Ident, char *Message, ...)
171 {
172         va_list args;
173         
174         va_start(args, Message);
175         Log_AddEvent(Ident, LOG_LEVEL_WARNING, Message, args);
176         va_end(args);
177 }
178
179 /**
180  * \brief Notice Message - Something the user might like to know
181  */
182 void Log_Notice(char *Ident, char *Message, ...)
183 {
184         va_list args;   
185         va_start(args, Message);
186         Log_AddEvent(Ident, LOG_LEVEL_NOTICE, Message, args);
187         va_end(args);
188 }
189
190 /**
191  * \brief Log Message - Possibly useful information
192  */
193 void Log_Log(char *Ident, char *Message, ...)
194 {
195         va_list args;   
196         va_start(args, Message);
197         Log_AddEvent(Ident, LOG_LEVEL_LOG, Message, args);
198         va_end(args);
199 }
200
201 /**
202  * \brief Debug Message - Only a developer would want this info
203  */
204 void Log_Debug(char *Ident, char *Message, ...)
205 {
206         va_list args;   
207         va_start(args, Message);
208         Log_AddEvent(Ident, LOG_LEVEL_DEBUG, Message, args);
209         va_end(args);
210 }

UCC git Repository :: git.ucc.asn.au