Rise
The Vieneo Province
Logger.cpp
Go to the documentation of this file.
1 #include "Logger.h"
2 
3 #include <io.h>
4 #include <fcntl.h>
5 #include <sys/stat.h>
6 #include "../Common/server.h"
7 #include "Networking.h"
8 #include <fstream>
9 #include <sstream>
10 
11 void Logger::Log(const char* msg, Level level, int errorCode)
12 {
13  lastError = msg;
14  lastLevel = level;
15  lastErrorCode = errorCode;
16 
17  SYSTEMTIME st;
18  GetLocalTime(&st);
19  char timemsg[999];
20  sprintf_s(timemsg, 999, "%02i:%02i:%02i.%03i ", st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
21  switch (level)
22  {
23  case Level::Warn:
24  strcat_s(timemsg, 999, "Warning: ");
25  break;
26  case Level::Debug:
27  strcat_s(timemsg, 999, "DEBUG: ");
28  break;
29  case Level::Error:
30  strcat_s(timemsg, 999, "ERROR: ");
31  break;
32  case Level::Fatal:
33  strcat_s(timemsg, 999, "FATAL: ");
34  break;
35  default:
36  break;
37  }
38  strcat_s(timemsg, 999, msg);
39  if (errorCode != 0)
40  {
41  char errorcodemsg[99];
42  sprintf_s(errorcodemsg, 99, " (0x%x)", errorCode);
43  strcat_s(timemsg, 999, errorcodemsg);
44  }
45  strcat_s(timemsg, 999, "\n");
46 
47  _write(logfile, timemsg, static_cast<unsigned int>(strlen(timemsg)));
48 
49  if (level == Level::Fatal || level == Level::Error || level == Level::Debug)
50  {
51  SErrorPacket errorPacket = SErrorPacket();
52  errorPacket.level = level;
53  sprintf_s(errorPacket.entry, 256, "%.255s", msg);
54  errorPacket.stackTrace[0] = 0;
55  for (int i = 4; i >= 0; i--)
56  {
57  strcat_s(errorPacket.stackTrace, 256, callStack[i]);
58  strcat_s(errorPacket.stackTrace, 256, "\n");
59  }
60 
61  networking->SendErrorReport(&errorPacket);
62  }
63 
64  if (level == Level::Fatal)
65  {
66  LogStackTrace();
67 
68  std::ifstream t(fileName);
69  std::stringstream buffer;
70  buffer << t.rdbuf();
71  networking->SendTraceFile(buffer.str().c_str());
72  networking->Flush();
73 
74  if (!DXUTIsWindowed())
75  {
76  DXUTToggleFullScreen();
77  SetCursor(LoadCursor(nullptr, IDC_ARROW));
78  }
79  MessageBoxA(DXUTGetHWND(), msg, "Fatal Exception", MB_ICONERROR | MB_OK);
80  networking->Close();
81  exit(errorCode);
82  }
83 }
84 
85 // add to back so newest is on bottom
86 void Logger::AddToCallStack(const char* msg)
87 {
88  for (int i = 0; i < 4; i++)
89  strcpy_s(callStack[i], 80, callStack[i + 1]);
90 
91  strcpy_s(callStack[4], 80, msg);
92 }
93 
94 // spits them out in the opposite order they were added ... so newest is on top
96 {
97  for (int i = 4; i >= 0; i--)
98  {
99  char line[80];
100  sprintf_s(line, 80, " --> %s", callStack[i]);
101  Log(line);
102  }
103 }
104 
106 {
107  networking = prmNetworking;
108 }
109 
110 void Logger::RemoveOldFiles(const wchar_t *searchkey, int maxDays)
111 {
112  WIN32_FIND_DATA fd;
113  HANDLE h = FindFirstFile(searchkey, &fd);
114  if (h == INVALID_HANDLE_VALUE)
115  {
116  return; // no files found
117  }
118  SYSTEMTIME st;
119  FILETIME ft;
120  GetLocalTime(&st);
121  SystemTimeToFileTime(&st, &ft);
122  while (true)
123  {
124  LONGLONG diffInTicks = reinterpret_cast<LARGE_INTEGER*>(&ft)->QuadPart - reinterpret_cast<LARGE_INTEGER*>(&fd.ftCreationTime)->QuadPart;
125  LONGLONG diffInMillis = diffInTicks / 10000;
126  LONGLONG diffInDays = diffInMillis / 86400000;
127  if (diffInDays > maxDays)
128  _wremove(fd.cFileName);
129  if (!FindNextFile(h, &fd))
130  break;
131  }
132 }
133 
135 {
136  // clean up old logs
137  RemoveOldFiles(L"trace_*.log", 7);
138 
139  SYSTEMTIME st;
140  GetLocalTime(&st);
141  sprintf_s(fileName, 99, "trace_%i-%02i-%02i-%02i%02i.log", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute);
142  _sopen_s(&logfile, fileName, _O_RDWR | _O_CREAT | _O_TEXT | _O_APPEND | _O_SEQUENTIAL, SH_DENYWR, S_IWRITE);
143  if (logfile == -1)
144  {
145  MessageBox(DXUTGetHWND(), L"Could not open logfile for writing!", L"Fatal Exception", MB_ICONERROR | MB_OK);
146  exit(errno);
147  }
148  char msg[99];
149  sprintf_s(msg, 99, "Logger::ctor Opened logfile \"%s\"", fileName);
150  Log(msg);
151 
152  for (int i = 0; i < 5; i++)
153  callStack[i][0] = 0;
154 }
155 
157 {
158  Log("Logger::dtor Closing logfile...");
159  _close(logfile);
160  logfile = -1;
161 }
char callStack[5][80]
Definition: Logger.h:36
~Logger()
Definition: Logger.cpp:156
void Close()
Definition: Networking.cpp:48
void SetNetworkingPointer(Networking *prmNetworking)
Definition: Logger.cpp:105
char fileName[99]
Definition: Logger.h:13
Level lastLevel
Definition: Logger.h:34
int lastErrorCode
Definition: Logger.h:35
std::string lastError
Definition: Logger.h:33
int logfile
Definition: Logger.h:11
void Log(const char *msg, Level level=Info, int errorCode=0)
Definition: Logger.cpp:11
static void RemoveOldFiles(const wchar_t *searchkey, int maxDays)
Definition: Logger.cpp:110
void LogStackTrace()
Definition: Logger.cpp:95
void Flush() const
Definition: Networking.cpp:158
void SendErrorReport(SErrorPacket *pData) const
Definition: Networking.cpp:93
void SendTraceFile(const char *fileContents) const
Definition: Networking.cpp:125
Level
Definition: Logger.h:19
void AddToCallStack(const char *msg)
Definition: Logger.cpp:86
Logger()
Definition: Logger.cpp:134
Networking * networking
Definition: Logger.h:12