1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/core/Logger.cpp Sat Mar 10 21:26:04 2007 +0000
1.3 @@ -0,0 +1,371 @@
1.4 +/**
1.5 + * ===============================================================
1.6 + * SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved.
1.7 + * ===============================================================
1.8 + *
1.9 + * This file is not open source and may not be copied without explicit
1.10 + * written permission of AlliedModders LLC. This file may not be redistributed
1.11 + * in whole or significant part.
1.12 + * For information, see LICENSE.txt or http://www.sourcemod.net/license.php
1.13 + *
1.14 + * Version: $Id$
1.15 + */
1.16 +
1.17 +#include <time.h>
1.18 +#include "sourcemod.h"
1.19 +#include "sourcemm_api.h"
1.20 +#include "Logger.h"
1.21 +#include "systems/LibrarySys.h"
1.22 +#include "sm_version.h"
1.23 +
1.24 +CLogger g_Logger;
1.25 +
1.26 +/**
1.27 + * :TODO: This should be creating the log folder if it doesn't exist
1.28 + */
1.29 +
1.30 +void CLogger::OnSourceModStartup(bool late)
1.31 +{
1.32 + //:TODO: read these options from a file, dont hardcode them
1.33 + InitLogger(LoggingMode_Daily, true);
1.34 +}
1.35 +
1.36 +void CLogger::OnSourceModAllShutdown()
1.37 +{
1.38 + CloseLogger();
1.39 +}
1.40 +
1.41 +void CLogger::_NewMapFile()
1.42 +{
1.43 + if (!m_Active)
1.44 + {
1.45 + return;
1.46 + }
1.47 +
1.48 + char _filename[256];
1.49 + int i = 0;
1.50 +
1.51 + time_t t;
1.52 + time(&t);
1.53 + tm *curtime = localtime(&t);
1.54 +
1.55 + while (true)
1.56 + {
1.57 + g_SourceMod.BuildPath(Path_SM, _filename, sizeof(_filename), "logs/logs_%02d%02d%03d.log", curtime->tm_mon + 1, curtime->tm_mday, i);
1.58 + FILE *fp = fopen(_filename, "r");
1.59 + if (!fp)
1.60 + {
1.61 + break;
1.62 + }
1.63 + fclose(fp);
1.64 + i++;
1.65 + }
1.66 + m_NrmFileName.assign(_filename);
1.67 +
1.68 + FILE *fp = fopen(m_NrmFileName.c_str(), "w");
1.69 + if (!fp)
1.70 + {
1.71 + g_SMAPI->ConPrint("[SM] Unexpected fatal logging error. SourceMod logging disabled.\n");
1.72 + m_Active = false;
1.73 + return;
1.74 + } else {
1.75 + char date[32];
1.76 + strftime(date, sizeof(date), "%m/%d/%Y - %H:%M:%S", curtime);
1.77 + fprintf(fp, "L %s: SourceMod log file started (file \"logs_%02d%02d%03d.log\") (Version \"%s\")\n", date, curtime->tm_mon + 1, curtime->tm_mday, i, SVN_FULL_VERSION);
1.78 + fclose(fp);
1.79 + }
1.80 +}
1.81 +
1.82 +void CLogger::_CloseFile()
1.83 +{
1.84 + if (!m_Active)
1.85 + {
1.86 + return;
1.87 + }
1.88 +
1.89 + FILE *fp = NULL;
1.90 + if (!m_NrmFileName.empty())
1.91 + {
1.92 + fp = fopen(m_NrmFileName.c_str(), "r+");
1.93 + if (fp)
1.94 + {
1.95 + fseek(fp, 0, SEEK_END);
1.96 + LogMessage("Log file closed.");
1.97 + fclose(fp);
1.98 + }
1.99 + m_NrmFileName.clear();
1.100 + }
1.101 +
1.102 + if (!m_ErrMapStart)
1.103 + {
1.104 + return;
1.105 + }
1.106 + fp = fopen(m_ErrFileName.c_str(), "r+");
1.107 + if (fp)
1.108 + {
1.109 + fseek(fp, 0, SEEK_END);
1.110 + LogError("Error log file session closed.");
1.111 + fclose(fp);
1.112 + }
1.113 + m_ErrFileName.clear();
1.114 +}
1.115 +
1.116 +void CLogger::InitLogger(LoggingMode mode, bool startlogging)
1.117 +{
1.118 + m_mode = mode;
1.119 + m_Active = startlogging;
1.120 +
1.121 + time_t t;
1.122 + time(&t);
1.123 + tm *curtime = localtime(&t);
1.124 + m_CurDay = curtime->tm_mday;
1.125 +
1.126 + char _filename[256];
1.127 + g_SourceMod.BuildPath(Path_SM, _filename, sizeof(_filename), "logs/errors_%02d%02d%02d.log", curtime->tm_mon + 1, curtime->tm_mday, curtime->tm_year - 100);
1.128 + m_ErrFileName.assign(_filename);
1.129 +
1.130 + switch (m_mode)
1.131 + {
1.132 + case LoggingMode_PerMap:
1.133 + {
1.134 + if (!startlogging)
1.135 + {
1.136 + m_DelayedStart = true;
1.137 + }
1.138 + break;
1.139 + }
1.140 + case LoggingMode_Daily:
1.141 + {
1.142 + g_SourceMod.BuildPath(Path_SM, _filename, sizeof(_filename), "logs/logs_%02d%02d.log", curtime->tm_mon + 1, curtime->tm_mday);
1.143 + m_NrmFileName.assign(_filename);
1.144 + m_DailyPrintHdr = true;
1.145 + break;
1.146 + }
1.147 + default:
1.148 + {
1.149 + /* do nothing... */
1.150 + break;
1.151 + }
1.152 + }
1.153 +}
1.154 +
1.155 +void CLogger::CloseLogger()
1.156 +{
1.157 + _CloseFile();
1.158 +}
1.159 +
1.160 +void CLogger::LogMessage(const char *vafmt, ...)
1.161 +{
1.162 + if (!m_Active)
1.163 + {
1.164 + return;
1.165 + }
1.166 +
1.167 + if (m_mode == LoggingMode_HL2)
1.168 + {
1.169 + va_list ap;
1.170 + va_start(ap, vafmt);
1.171 + _PrintToHL2Log(vafmt, ap);
1.172 + va_end(ap);
1.173 + return;
1.174 + }
1.175 +
1.176 + if (m_DelayedStart)
1.177 + {
1.178 + m_DelayedStart = false;
1.179 + _NewMapFile();
1.180 + }
1.181 +
1.182 + char msg[3072];
1.183 + va_list ap;
1.184 + va_start(ap, vafmt);
1.185 + vsnprintf(msg, sizeof(msg), vafmt, ap);
1.186 + va_end(ap);
1.187 +
1.188 + char date[32];
1.189 + time_t t;
1.190 + time(&t);
1.191 + tm *curtime = localtime(&t);
1.192 + strftime(date, sizeof(date), "%m/%d/%Y - %H:%M:%S", curtime);
1.193 +
1.194 + FILE *fp = NULL;
1.195 + if (m_mode == LoggingMode_PerMap)
1.196 + {
1.197 + fp = fopen(m_NrmFileName.c_str(), "a+");
1.198 + if (!fp)
1.199 + {
1.200 + _NewMapFile();
1.201 + fp = fopen(m_NrmFileName.c_str(), "a+");
1.202 + if (!fp)
1.203 + {
1.204 + goto print_error;
1.205 + }
1.206 + }
1.207 + } else {
1.208 + if (m_CurDay != curtime->tm_mday)
1.209 + {
1.210 + char _filename[256];
1.211 + g_SourceMod.BuildPath(Path_SM, _filename, sizeof(_filename), "logs/logs_%02d%02d.log", curtime->tm_mon + 1, curtime->tm_mday);
1.212 + m_NrmFileName.assign(_filename);
1.213 + m_CurDay = curtime->tm_mday;
1.214 + m_DailyPrintHdr = true;
1.215 + }
1.216 + fp = fopen(m_NrmFileName.c_str(), "a+");
1.217 + }
1.218 +
1.219 + if (fp)
1.220 + {
1.221 + if (m_DailyPrintHdr)
1.222 + {
1.223 + m_DailyPrintHdr = false;
1.224 + fprintf(fp, "L %s: SourceMod log file session started (file \"logs_%02d%02d.log\") (Version \"%s\")\n", date, curtime->tm_mon + 1, curtime->tm_mday, SVN_FULL_VERSION);
1.225 + }
1.226 + fprintf(fp, "L %s: %s\n", date, msg);
1.227 + fclose(fp);
1.228 + } else {
1.229 + goto print_error;
1.230 + }
1.231 +
1.232 + g_SMAPI->ConPrintf("L %s: %s\n", date, msg);
1.233 + return;
1.234 +print_error:
1.235 + g_SMAPI->ConPrint("[SM] Unexpected fatal logging error. SourceMod logging disabled.\n");
1.236 + m_Active = false;
1.237 +}
1.238 +
1.239 +void CLogger::LogError(const char *vafmt, ...)
1.240 +{
1.241 + if (!m_Active)
1.242 + {
1.243 + return;
1.244 + }
1.245 +
1.246 + time_t t;
1.247 + time(&t);
1.248 + tm *curtime = localtime(&t);
1.249 +
1.250 + char date[32];
1.251 + strftime(date, sizeof(date), "%m/%d/%Y - %H:%M:%S", curtime);
1.252 +
1.253 + if (curtime->tm_mday != m_CurDay)
1.254 + {
1.255 + char _filename[256];
1.256 + g_SourceMod.BuildPath(Path_SM, _filename, sizeof(_filename), "logs/errors_%02d%02d%02d.log", curtime->tm_mon + 1, curtime->tm_mday, curtime->tm_year - 100);
1.257 + m_ErrFileName.assign(_filename);
1.258 + m_CurDay = curtime->tm_mday;
1.259 + m_ErrMapStart = false;
1.260 + }
1.261 +
1.262 + char msg[3072];
1.263 + va_list ap;
1.264 + va_start(ap, vafmt);
1.265 + vsnprintf(msg, sizeof(msg), vafmt, ap);
1.266 + va_end(ap);
1.267 +
1.268 + FILE *fp = fopen(m_ErrFileName.c_str(), "a+");
1.269 + if (fp)
1.270 + {
1.271 + if (!m_ErrMapStart)
1.272 + {
1.273 + fprintf(fp, "L %s: SourceMod error session started\n", date);
1.274 + fprintf(fp, "L %s: Info (map \"%s\") (log file \"errors_%02d%02d%02d.log\")\n", date, m_CurMapName.c_str(), curtime->tm_mon + 1, curtime->tm_mday, curtime->tm_year - 100);
1.275 + m_ErrMapStart = true;
1.276 + }
1.277 + fprintf(fp, "L %s: %s\n", date, msg);
1.278 + fclose(fp);
1.279 + } else {
1.280 + g_SMAPI->ConPrint("[SM] Unexpected fatal logging error. SourceMod logging disabled.\n");
1.281 + m_Active = false;
1.282 + return;
1.283 + }
1.284 +
1.285 + g_SMAPI->ConPrintf("L %s: %s\n", date, msg);
1.286 +}
1.287 +
1.288 +void CLogger::MapChange(const char *mapname)
1.289 +{
1.290 + m_CurMapName.assign(mapname);
1.291 +
1.292 + switch (m_mode)
1.293 + {
1.294 + case LoggingMode_Daily:
1.295 + {
1.296 + LogMessage("-------- Mapchange to %s --------", mapname);
1.297 + break;
1.298 + }
1.299 + case LoggingMode_PerMap:
1.300 + {
1.301 + _NewMapFile();
1.302 + break;
1.303 + }
1.304 + default:
1.305 + {
1.306 + /* Do nothing... */
1.307 + break;
1.308 + }
1.309 + }
1.310 +
1.311 + if (m_ErrMapStart)
1.312 + {
1.313 + LogError("Error log file session closed.");
1.314 + }
1.315 + m_ErrMapStart = false;
1.316 +}
1.317 +
1.318 +void CLogger::_PrintToHL2Log(const char *fmt, va_list ap)
1.319 +{
1.320 + char msg[3072];
1.321 + size_t len;
1.322 +
1.323 + len = vsnprintf(msg, sizeof(msg)-2, fmt, ap);
1.324 + len = (len >= sizeof(msg)) ? (sizeof(msg) - 2) : len;
1.325 +
1.326 + msg[len++] = '\n';
1.327 + msg[len] = '\0';
1.328 +
1.329 + engine->LogPrint(msg);
1.330 +}
1.331 +
1.332 +const char *CLogger::GetLogFileName(LogType type) const
1.333 +{
1.334 + switch (type)
1.335 + {
1.336 + case LogType_Normal:
1.337 + {
1.338 + return m_NrmFileName.c_str();
1.339 + }
1.340 + case LogType_Error:
1.341 + {
1.342 + return m_ErrFileName.c_str();
1.343 + }
1.344 + default:
1.345 + {
1.346 + return "";
1.347 + }
1.348 + }
1.349 +}
1.350 +
1.351 +LoggingMode CLogger::GetLoggingMode() const
1.352 +{
1.353 + return m_mode;
1.354 +}
1.355 +
1.356 +void CLogger::EnableLogging()
1.357 +{
1.358 + if (m_Active)
1.359 + {
1.360 + return;
1.361 + }
1.362 + m_Active = true;
1.363 + LogMessage("Logging enabled manually by user.");
1.364 +}
1.365 +
1.366 +void CLogger::DisableLogging()
1.367 +{
1.368 + if (!m_Active)
1.369 + {
1.370 + return;
1.371 + }
1.372 + LogMessage("Logging disabled manually by user.");
1.373 + m_Active = false;
1.374 +}