Repository navigation
Expand file tree
/
Copy pathLogger.h
More file actions
156 lines (139 loc) · 4.03 KB
/
Copy pathLogger.h
File metadata and controls
156 lines (139 loc) · 4.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
/*
* Copyright 2010-2013 OpenXcom Developers.
*
* This file is part of OpenXcom.
*
* OpenXcom is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenXcom is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenXcom. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OPENXCOM_LOGGER_H
#define OPENXCOM_LOGGER_H
#include <sstream>
#include <string>
#include <stdio.h>
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
// the following macros interfere with std::max and std::min as used throughout...
#undef min
#undef max
#ifndef LOCALE_INVARIANT
#define LOCALE_INVARIANT 0x007f
#endif
#else
#include <time.h>
#endif
namespace OpenXcom
{
inline std::string now();
/**
* Defines the various severity levels of
* information logged by the game.
*/
enum SeverityLevel
{
LOG_FATAL, /**< Something horrible has happened and the game is going to die! */
LOG_ERROR, /**< Something bad happened but we can still move on. */
LOG_WARNING, /**< Something weird happened, nothing special but it's good to know. */
LOG_INFO, /**< Useful information for users/developers to help debug and figure stuff out. */
LOG_DEBUG /**< Purely test stuff to help developers implement, not really relevant to users. */
};
/**
* A basic logging and debugging class, prints output to stdout/files
* and can capture stack traces of fatal errors too.
* @note Wasn't really satisfied with any of the libraries around
* so I rolled my own. Based on http://www.drdobbs.com/cpp/logging-in-c/201804215
*/
class Logger
{
public:
Logger();
virtual ~Logger();
std::ostringstream& get(SeverityLevel level = LOG_INFO);
static SeverityLevel& reportingLevel();
static std::string& logFile();
static std::string toString(SeverityLevel level);
protected:
std::ostringstream os;
private:
Logger(const Logger&);
Logger& operator =(const Logger&);
};
inline Logger::Logger()
{
}
inline std::ostringstream& Logger::get(SeverityLevel level)
{
os << "[" << toString(level) << "]" << "\t";
return os;
}
inline Logger::~Logger()
{
os << std::endl;
if (reportingLevel() == LOG_DEBUG)
{
fprintf(stderr, "%s", os.str().c_str());
fflush(stderr);
}
std::ostringstream ss;
ss << "[" << now() << "]" << "\t" << os.str();
FILE *file = fopen(logFile().c_str(), "a");
fprintf(file, "%s", ss.str().c_str());
fflush(file);
fclose(file);
}
inline SeverityLevel& Logger::reportingLevel()
{
static SeverityLevel reportingLevel = LOG_DEBUG;
return reportingLevel;
}
inline std::string& Logger::logFile()
{
static std::string logFile = "openxcom.log";
return logFile;
}
inline std::string Logger::toString(SeverityLevel level)
{
static const char* const buffer[] = {"FATAL", "ERROR", "WARN", "INFO", "DEBUG"};
return buffer[level];
}
#define Log(level) \
if (level > Logger::reportingLevel()) ; \
else Logger().get(level)
inline std::string now()
{
const int MAX_LEN = 25, MAX_RESULT = 80;
#ifdef _WIN32
char date[MAX_LEN], time[MAX_LEN];
if (GetDateFormatA(LOCALE_INVARIANT, 0, 0,
"dd'-'MM'-'yyyy", date, MAX_LEN) == 0)
return "Error in Now()";
if (GetTimeFormatA(LOCALE_INVARIANT, TIME_FORCE24HOURFORMAT, 0,
"HH':'mm':'ss", time, MAX_LEN) == 0)
return "Error in Now()";
char result[MAX_RESULT] = {0};
sprintf(result, "%s %s", date, time);
#else
char buffer[MAX_LEN];
time_t rawtime;
struct tm *timeinfo;
time(&rawtime);
timeinfo = localtime(&rawtime);
strftime(buffer, MAX_LEN, "%d-%m-%Y %H:%M:%S", timeinfo);
char result[MAX_RESULT] = {0};
sprintf(result, "%s", buffer);
#endif
return result;
}
}
#endif