Bugfixing
[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
58 // === EXPORTS ===
59 EXPORT(Log_Panic);
60 EXPORT(Log_Error);
61 EXPORT(Log_Warning);
62 EXPORT(Log_Notice);
63 EXPORT(Log_Log);
64 EXPORT(Log_Debug);
65
66 // === GLOBALS ===
67 tSpinlock       glLog;
68 tSpinlock       glLogOutput;
69 tLogList        gLog;
70 tLogList        gLog_Levels[NUM_LOG_LEVELS];
71
72 // === CODE ===
73 /**
74  * \brief Adds an event to the log
75  */
76 void Log_AddEvent(char *Ident, int Level, char *Format, va_list Args)
77 {
78          int    len;
79         tLogEntry       *ent;
80         
81         if( Level >= NUM_LOG_LEVELS )   return;
82         
83         len = vsnprintf(NULL, 256, Format, Args);
84         
85         //Log("len = %i", len);
86         
87         ent = malloc(sizeof(tLogEntry)+len+1);
88         ent->Time = now();
89         strncpy(ent->Ident, Ident, 8);
90         ent->Level = Level;
91         ent->Length = len;
92         vsnprintf( ent->Data, 256, Format, Args );
93         
94         //Log("ent->Ident = '%s'", ent->Ident);
95         //Log("ent->Data = '%s'", ent->Data);
96         
97         LOCK( &glLog );
98         
99         ent->Next = gLog.Tail;
100         if(gLog.Head)
101                 gLog.Tail = ent;
102         else
103                 gLog.Tail = gLog.Head = ent;
104         
105         ent->LevelNext = gLog_Levels[Level].Tail;
106         if(gLog_Levels[Level].Head)
107                 gLog_Levels[Level].Tail = ent;
108         else
109                 gLog_Levels[Level].Tail = gLog_Levels[Level].Head = ent;
110         
111         RELEASE( &glLog );
112         
113         #if PRINT_ON_APPEND
114         Log_Int_PrintMessage( ent );
115         #endif
116         
117 }
118
119 /**
120  * \brief Prints a log message to the debug console
121  */
122 void Log_Int_PrintMessage(tLogEntry *Entry)
123 {
124         LogF("%s%018lli%s [%+8s] %s\x1B[0m\n",
125                 csaLevelColours[Entry->Level],
126                 Entry->Time,
127                 csaLevelCodes[Entry->Level],
128                 Entry->Ident,
129                 Entry->Data
130                 );
131 }
132
133 /**
134  * \brief KERNEL PANIC!!!!
135  */
136 void Log_KernelPanic(char *Ident, char *Message, ...)
137 {
138         va_list args;   
139         va_start(args, Message);
140         Log_AddEvent(Ident, LOG_LEVEL_KPANIC, Message, args);
141         va_end(args);
142 }
143
144 /**
145  * \brief Panic Message - Driver Unrecoverable error
146  */
147 void Log_Panic(char *Ident, char *Message, ...)
148 {
149         va_list args;   
150         va_start(args, Message);
151         Log_AddEvent(Ident, LOG_LEVEL_PANIC, Message, args);
152         va_end(args);
153 }
154
155 /**
156  * \brief Error Message - Recoverable Error
157  */
158 void Log_Error(char *Ident, char *Message, ...)
159 {
160         va_list args;   
161         va_start(args, Message);
162         Log_AddEvent(Ident, LOG_LEVEL_ERROR, Message, args);
163         va_end(args);
164 }
165
166 /**
167  * \brief Warning Message - Something the user should know
168  */
169 void Log_Warning(char *Ident, char *Message, ...)
170 {
171         va_list args;
172         
173         va_start(args, Message);
174         Log_AddEvent(Ident, LOG_LEVEL_WARNING, Message, args);
175         va_end(args);
176 }
177
178 /**
179  * \brief Notice Message - Something the user might like to know
180  */
181 void Log_Notice(char *Ident, char *Message, ...)
182 {
183         va_list args;   
184         va_start(args, Message);
185         Log_AddEvent(Ident, LOG_LEVEL_NOTICE, Message, args);
186         va_end(args);
187 }
188
189 /**
190  * \brief Log Message - Possibly useful information
191  */
192 void Log_Log(char *Ident, char *Message, ...)
193 {
194         va_list args;   
195         va_start(args, Message);
196         Log_AddEvent(Ident, LOG_LEVEL_LOG, Message, args);
197         va_end(args);
198 }
199
200 /**
201  * \brief Debug Message - Only a developer would want this info
202  */
203 void Log_Debug(char *Ident, char *Message, ...)
204 {
205         va_list args;   
206         va_start(args, Message);
207         Log_AddEvent(Ident, LOG_LEVEL_DEBUG, Message, args);
208         va_end(args);
209 }

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