/src/ogre/OgreMain/src/OgreLog.cpp
Line | Count | Source |
1 | | /* |
2 | | ----------------------------------------------------------------------------- |
3 | | This source file is part of OGRE |
4 | | (Object-oriented Graphics Rendering Engine) |
5 | | For the latest info, see http://www.ogre3d.org/ |
6 | | |
7 | | Copyright (c) 2000-2014 Torus Knot Software Ltd |
8 | | |
9 | | Permission is hereby granted, free of charge, to any person obtaining a copy |
10 | | of this software and associated documentation files (the "Software"), to deal |
11 | | in the Software without restriction, including without limitation the rights |
12 | | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
13 | | copies of the Software, and to permit persons to whom the Software is |
14 | | furnished to do so, subject to the following conditions: |
15 | | |
16 | | The above copyright notice and this permission notice shall be included in |
17 | | all copies or substantial portions of the Software. |
18 | | |
19 | | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
20 | | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
21 | | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
22 | | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
23 | | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
24 | | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
25 | | THE SOFTWARE. |
26 | | ----------------------------------------------------------------------------- |
27 | | */ |
28 | | #include "OgreStableHeaders.h" |
29 | | |
30 | | #include <iostream> |
31 | | |
32 | | #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WINRT |
33 | | # include <windows.h> |
34 | | # if _WIN32_WINNT >= _WIN32_WINNT_VISTA |
35 | | # include <werapi.h> |
36 | | # endif |
37 | | #endif |
38 | | |
39 | | // LogMessageLevel + LoggingLevel > OGRE_LOG_THRESHOLD = message logged |
40 | 0 | #define OGRE_LOG_THRESHOLD 4 |
41 | | |
42 | | namespace { |
43 | | const char* RED = "\x1b[31;1m"; |
44 | | const char* YELLOW = "\x1b[33;1m"; |
45 | | const char* RESET = "\x1b[0m"; |
46 | | } |
47 | | |
48 | | namespace Ogre |
49 | | { |
50 | | //----------------------------------------------------------------------- |
51 | | Log::Log( const String& name, bool debuggerOutput, bool suppressFile ) : |
52 | 1 | mLogLevel(LML_NORMAL), mDebugOut(debuggerOutput), |
53 | 1 | mSuppressFile(suppressFile), mTimeStamp(true), mLogName(name), mTermHasColours(false) |
54 | 1 | { |
55 | 1 | if (!mSuppressFile) |
56 | 1 | { |
57 | 1 | mLog.open(name.c_str()); |
58 | | |
59 | | #if (OGRE_PLATFORM == OGRE_PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WINRT) && _WIN32_WINNT >= _WIN32_WINNT_VISTA |
60 | | // Register log file to be collected by Windows Error Reporting |
61 | | const int utf16Length = ::MultiByteToWideChar(CP_ACP, 0, name.c_str(), (int)name.size(), NULL, 0); |
62 | | if(utf16Length > 0) |
63 | | { |
64 | | std::wstring wname; |
65 | | wname.resize(utf16Length); |
66 | | if (0 != ::MultiByteToWideChar(CP_ACP, 0, name.c_str(), (int)name.size(), &wname[0], (int)wname.size())) |
67 | | WerRegisterFile(wname.c_str(), WerRegFileTypeOther, WER_FILE_ANONYMOUS_DATA); |
68 | | } |
69 | | #endif |
70 | 1 | } |
71 | | |
72 | 1 | #if OGRE_PLATFORM != OGRE_PLATFORM_WINRT |
73 | 1 | char* val = getenv("OGRE_MIN_LOGLEVEL"); |
74 | 1 | int min_lml; |
75 | 1 | if(val && StringConverter::parse(val, min_lml)) |
76 | 0 | setMinLogLevel(LogMessageLevel(min_lml)); |
77 | | |
78 | 1 | if(mDebugOut) |
79 | 0 | { |
80 | 0 | val = getenv("TERM"); |
81 | 0 | mTermHasColours = val && String(val).find("xterm") != String::npos; |
82 | 0 | } |
83 | 1 | #endif |
84 | 1 | } |
85 | | //----------------------------------------------------------------------- |
86 | | Log::~Log() |
87 | 0 | { |
88 | 0 | OGRE_LOCK_AUTO_MUTEX; |
89 | 0 | if (!mSuppressFile) |
90 | 0 | { |
91 | 0 | mLog.close(); |
92 | 0 | } |
93 | 0 | } |
94 | | |
95 | | //----------------------------------------------------------------------- |
96 | | void Log::logMessage( const String& message, LogMessageLevel lml, bool maskDebug ) |
97 | 24.1k | { |
98 | 24.1k | OGRE_LOCK_AUTO_MUTEX; |
99 | 24.1k | if (lml >= mLogLevel) |
100 | 24.1k | { |
101 | 24.1k | bool skipThisMessage = false; |
102 | 24.1k | for(auto & l : mListeners) |
103 | 0 | l->messageLogged( message, lml, maskDebug, mLogName, skipThisMessage); |
104 | | |
105 | 24.1k | if (!skipThisMessage) |
106 | 24.1k | { |
107 | 24.1k | if (mDebugOut && !maskDebug) |
108 | 0 | { |
109 | | # if (OGRE_PLATFORM == OGRE_PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WINRT) && OGRE_DEBUG_MODE |
110 | | OutputDebugStringA("Ogre: "); |
111 | | OutputDebugStringA(message.c_str()); |
112 | | OutputDebugStringA("\n"); |
113 | | # endif |
114 | |
|
115 | 0 | std::ostream& os = int(lml) >= int(LML_WARNING) ? std::cerr : std::cout; |
116 | |
|
117 | 0 | if(mTermHasColours) { |
118 | 0 | if(lml == LML_WARNING) |
119 | 0 | os << YELLOW; |
120 | 0 | if(lml == LML_CRITICAL) |
121 | 0 | os << RED; |
122 | 0 | } |
123 | |
|
124 | 0 | os << message; |
125 | |
|
126 | 0 | if(mTermHasColours) { |
127 | 0 | os << RESET; |
128 | 0 | } |
129 | |
|
130 | 0 | os << std::endl; |
131 | 0 | } |
132 | | |
133 | | // Write time into log |
134 | 24.1k | if (!mSuppressFile) |
135 | 24.1k | { |
136 | 24.1k | if (mTimeStamp) |
137 | 24.1k | { |
138 | 24.1k | auto t = std::time(nullptr); |
139 | 24.1k | auto pTime = std::localtime(&t); |
140 | 24.1k | mLog << std::put_time(pTime, "%H:%M:%S: "); |
141 | 24.1k | } |
142 | 24.1k | mLog << message << std::endl; |
143 | | |
144 | | // Flush stcmdream to ensure it is written (incase of a crash, we need log to be up to date) |
145 | 24.1k | mLog.flush(); |
146 | 24.1k | } |
147 | 24.1k | } |
148 | 24.1k | } |
149 | 24.1k | } |
150 | | |
151 | | //----------------------------------------------------------------------- |
152 | | void Log::setTimeStampEnabled(bool timeStamp) |
153 | 0 | { |
154 | 0 | OGRE_LOCK_AUTO_MUTEX; |
155 | 0 | mTimeStamp = timeStamp; |
156 | 0 | } |
157 | | |
158 | | //----------------------------------------------------------------------- |
159 | | void Log::setDebugOutputEnabled(bool debugOutput) |
160 | 0 | { |
161 | 0 | OGRE_LOCK_AUTO_MUTEX; |
162 | 0 | mDebugOut = debugOutput; |
163 | 0 | } |
164 | | |
165 | | //----------------------------------------------------------------------- |
166 | | void Log::setLogDetail(LoggingLevel ll) |
167 | 0 | { |
168 | 0 | OGRE_LOCK_AUTO_MUTEX; |
169 | 0 | mLogLevel = LogMessageLevel(OGRE_LOG_THRESHOLD - ll); |
170 | 0 | } |
171 | | |
172 | | void Log::setMinLogLevel(LogMessageLevel lml) |
173 | 1 | { |
174 | 1 | OGRE_LOCK_AUTO_MUTEX; |
175 | 1 | mLogLevel = lml; |
176 | 1 | } |
177 | | |
178 | | //----------------------------------------------------------------------- |
179 | | void Log::addListener(LogListener* listener) |
180 | 0 | { |
181 | 0 | OGRE_LOCK_AUTO_MUTEX; |
182 | 0 | if (std::find(mListeners.begin(), mListeners.end(), listener) == mListeners.end()) |
183 | 0 | mListeners.push_back(listener); |
184 | 0 | } |
185 | | |
186 | | //----------------------------------------------------------------------- |
187 | | void Log::removeListener(LogListener* listener) |
188 | 0 | { |
189 | 0 | OGRE_LOCK_AUTO_MUTEX; |
190 | 0 | mtLogListener::iterator i = std::find(mListeners.begin(), mListeners.end(), listener); |
191 | 0 | if (i != mListeners.end()) |
192 | 0 | mListeners.erase(i); |
193 | 0 | } |
194 | | //--------------------------------------------------------------------- |
195 | | Log::Stream Log::stream(LogMessageLevel lml, bool maskDebug) |
196 | 0 | { |
197 | 0 | return Stream(this, lml, maskDebug); |
198 | |
|
199 | 0 | } |
200 | | } |