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

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