core/Logger.cpp
author Scott Ehlert <ds@alliedmods.net>
Thu Mar 22 21:50:20 2007 +0000 (2007-03-22)
changeset 653 ef60870067ff
parent 616 d5b1dcf38c07
child 661 5c0988b9bf0c
permissions -rw-r--r--
More consistency of some sort...

Oh god, what has possessed me to do this?
     1 /**
     2  * vim: set ts=4 :
     3  * ===============================================================
     4  * SourceMod (C)2004-2007 AlliedModders LLC.  All rights reserved.
     5  * ===============================================================
     6  *
     7  * This file is not open source and may not be copied without explicit
     8  * written permission of AlliedModders LLC.  This file may not be redistributed 
     9  * in whole or significant part.
    10  * For information, see LICENSE.txt or http://www.sourcemod.net/license.php
    11  *
    12  * Version: $Id$
    13  */
    14 
    15 #include <time.h>
    16 #include "sourcemod.h"
    17 #include "sourcemm_api.h"
    18 #include "Logger.h"
    19 #include "systems/LibrarySys.h"
    20 #include "sm_version.h"
    21 
    22 Logger g_Logger;
    23 
    24 /**
    25  * :TODO: This should be creating the log folder if it doesn't exist
    26  */
    27 
    28 void Logger::OnSourceModStartup(bool late)
    29 {
    30 	//:TODO: read these options from a file, dont hardcode them
    31 	InitLogger(LoggingMode_Daily, true);
    32 }
    33 
    34 void Logger::OnSourceModAllShutdown()
    35 {
    36 	CloseLogger();
    37 }
    38 
    39 void Logger::_NewMapFile()
    40 {
    41 	if (!m_Active)
    42 	{
    43 		return;
    44 	}
    45 	
    46 	char _filename[256];
    47 	int i = 0;
    48 
    49 	time_t t;
    50 	time(&t);
    51 	tm *curtime = localtime(&t);
    52 
    53 	while (true)
    54 	{
    55 		g_SourceMod.BuildPath(Path_SM, _filename, sizeof(_filename), "logs/logs_%02d%02d%03d.log", curtime->tm_mon + 1, curtime->tm_mday, i);
    56 		FILE *fp = fopen(_filename, "r");
    57 		if (!fp)
    58 		{
    59 			break;
    60 		}
    61 		fclose(fp);
    62 		i++;
    63 	}
    64 	m_NrmFileName.assign(_filename);
    65 
    66 	FILE *fp = fopen(m_NrmFileName.c_str(), "w");
    67 	if (!fp)
    68 	{
    69 		g_SMAPI->ConPrint("[SM] Unexpected fatal logging error. SourceMod logging disabled.\n");
    70 		m_Active = false;
    71 		return;
    72 	} else {
    73 		char date[32];
    74 		strftime(date, sizeof(date), "%m/%d/%Y - %H:%M:%S", curtime);
    75 		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);
    76 		fclose(fp);
    77 	}
    78 }
    79 
    80 void Logger::_CloseFile()
    81 {
    82 	if (!m_Active)
    83 	{
    84 		return;
    85 	}
    86 
    87 	FILE *fp = NULL;
    88 	if (!m_NrmFileName.empty())
    89 	{
    90 		fp = fopen(m_NrmFileName.c_str(), "r+");
    91 		if (fp)
    92 		{
    93 			fseek(fp, 0, SEEK_END);
    94 			LogMessage("Log file closed.");
    95 			fclose(fp);
    96 		}
    97 		m_NrmFileName.clear();
    98 	}
    99 
   100 	if (!m_ErrMapStart)
   101 	{
   102 		return;
   103 	}
   104 	fp = fopen(m_ErrFileName.c_str(), "r+");
   105 	if (fp)
   106 	{
   107 		fseek(fp, 0, SEEK_END);
   108 		LogError("Error log file session closed.");
   109 		fclose(fp);
   110 	}
   111 	m_ErrFileName.clear();
   112 }
   113 
   114 void Logger::InitLogger(LoggingMode mode, bool startlogging)
   115 {
   116 	m_mode = mode;
   117 	m_Active = startlogging;
   118 
   119 	time_t t;
   120 	time(&t);
   121 	tm *curtime = localtime(&t);
   122 	m_CurDay = curtime->tm_mday;
   123 
   124 	char _filename[256];
   125 	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);
   126 	m_ErrFileName.assign(_filename);
   127 
   128 	switch (m_mode)
   129 	{
   130 	case LoggingMode_PerMap:
   131 		{
   132 			if (!startlogging)
   133 			{
   134 				m_DelayedStart = true;
   135 			}
   136 			break;
   137 		}
   138 	case LoggingMode_Daily:
   139 		{
   140 			g_SourceMod.BuildPath(Path_SM, _filename, sizeof(_filename), "logs/logs_%02d%02d.log", curtime->tm_mon + 1, curtime->tm_mday);
   141 			m_NrmFileName.assign(_filename);
   142 			m_DailyPrintHdr = true;
   143 			break;
   144 		}
   145 	default:
   146 		{
   147 			/* do nothing... */
   148 			break;
   149 		}
   150 	}
   151 }
   152 
   153 void Logger::CloseLogger()
   154 {
   155 	_CloseFile();
   156 }
   157 
   158 void Logger::LogMessage(const char *vafmt, ...)
   159 {
   160 	if (!m_Active)
   161 	{
   162 		return;
   163 	}
   164 
   165 	if (m_mode == LoggingMode_HL2)
   166 	{
   167 		va_list ap;
   168 		va_start(ap, vafmt);
   169 		_PrintToHL2Log(vafmt, ap);
   170 		va_end(ap);
   171 		return;
   172 	}
   173 
   174 	if (m_DelayedStart)
   175 	{
   176 		m_DelayedStart = false;
   177 		_NewMapFile();
   178 	}
   179 
   180 	char msg[3072];
   181 	va_list ap;
   182 	va_start(ap, vafmt);
   183 	vsnprintf(msg, sizeof(msg), vafmt, ap);
   184 	va_end(ap);
   185 
   186 	char date[32];
   187 	time_t t;
   188 	time(&t);
   189 	tm *curtime = localtime(&t);
   190 	strftime(date, sizeof(date), "%m/%d/%Y - %H:%M:%S", curtime);
   191 
   192 	FILE *fp = NULL;
   193 	if (m_mode == LoggingMode_PerMap)
   194 	{
   195 		fp = fopen(m_NrmFileName.c_str(), "a+");
   196 		if (!fp)
   197 		{
   198 			_NewMapFile();
   199 			fp = fopen(m_NrmFileName.c_str(), "a+");
   200 			if (!fp)
   201 			{
   202 				goto print_error;
   203 			}
   204 		}
   205 	} else {
   206 		if (m_CurDay != curtime->tm_mday)
   207 		{
   208 			char _filename[256];
   209 			g_SourceMod.BuildPath(Path_SM, _filename, sizeof(_filename), "logs/logs_%02d%02d.log", curtime->tm_mon + 1, curtime->tm_mday);
   210 			m_NrmFileName.assign(_filename);
   211 			m_CurDay = curtime->tm_mday;
   212 			m_DailyPrintHdr = true;
   213 		}
   214 		fp = fopen(m_NrmFileName.c_str(), "a+");
   215 	}
   216 
   217 	if (fp)
   218 	{
   219 		if (m_DailyPrintHdr)
   220 		{
   221 			m_DailyPrintHdr = false;
   222 			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);
   223 	 	}
   224 		fprintf(fp, "L %s: %s\n", date, msg);
   225 		fclose(fp);
   226 	} else {
   227 		goto print_error;
   228 	}
   229 
   230 	g_SMAPI->ConPrintf("L %s: %s\n", date, msg);
   231 	return;
   232 print_error:
   233 	g_SMAPI->ConPrint("[SM] Unexpected fatal logging error. SourceMod logging disabled.\n");
   234 	m_Active = false;
   235 }
   236 
   237 void Logger::LogError(const char *vafmt, ...)
   238 {
   239 	if (!m_Active)
   240 	{
   241 		return;
   242 	}
   243 
   244 	time_t t;
   245 	time(&t);
   246 	tm *curtime = localtime(&t);
   247 
   248 	char date[32];
   249 	strftime(date, sizeof(date), "%m/%d/%Y - %H:%M:%S", curtime);
   250 
   251 	if (curtime->tm_mday != m_CurDay)
   252 	{
   253 		char _filename[256];
   254 		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);
   255 		m_ErrFileName.assign(_filename);
   256 		m_CurDay = curtime->tm_mday;
   257 		m_ErrMapStart = false;
   258 	}
   259 
   260 	char msg[3072];
   261 	va_list ap;
   262 	va_start(ap, vafmt);
   263 	vsnprintf(msg, sizeof(msg), vafmt, ap);
   264 	va_end(ap);
   265 
   266 	FILE *fp = fopen(m_ErrFileName.c_str(), "a+");
   267 	if (fp)
   268 	{
   269 		if (!m_ErrMapStart)
   270 		{
   271 			fprintf(fp, "L %s: SourceMod error session started\n", date);
   272 			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);
   273 			m_ErrMapStart = true;
   274 		}
   275 		fprintf(fp, "L %s: %s\n", date, msg);
   276 		fclose(fp);
   277 	} else {
   278 		g_SMAPI->ConPrint("[SM] Unexpected fatal logging error. SourceMod logging disabled.\n");
   279 		m_Active = false;
   280 		return;
   281 	}
   282 
   283 	g_SMAPI->ConPrintf("L %s: %s\n", date, msg);
   284 }
   285 
   286 void Logger::MapChange(const char *mapname)
   287 {
   288 	m_CurMapName.assign(mapname);
   289 
   290 	switch (m_mode)
   291 	{
   292 	case LoggingMode_Daily:
   293 		{
   294 			LogMessage("-------- Mapchange to %s --------", mapname);
   295 			break;
   296 		}
   297 	case LoggingMode_PerMap:
   298 		{
   299 			_NewMapFile();
   300 			break;
   301 		}
   302 	default:
   303 		{
   304 			/* Do nothing... */
   305 			break;
   306 		}
   307 	}
   308 
   309 	if (m_ErrMapStart)
   310 	{
   311 		LogError("Error log file session closed.");
   312 	}
   313 	m_ErrMapStart = false;
   314 }
   315 
   316 void Logger::_PrintToHL2Log(const char *fmt, va_list ap)
   317 {
   318 	char msg[3072];
   319 	size_t len;
   320 
   321 	len = vsnprintf(msg, sizeof(msg)-2, fmt, ap);
   322 	len = (len >= sizeof(msg)) ? (sizeof(msg) - 2) : len;
   323 
   324 	msg[len++] = '\n';
   325 	msg[len] = '\0';
   326 
   327 	engine->LogPrint(msg);
   328 }
   329 
   330 const char *Logger::GetLogFileName(LogType type) const
   331 {
   332 	switch (type)
   333 	{
   334 	case LogType_Normal:
   335 		{
   336 			return m_NrmFileName.c_str();
   337 		}
   338 	case LogType_Error:
   339 		{
   340 			return m_ErrFileName.c_str();
   341 		}
   342 	default:
   343 		{
   344 			return "";
   345 		}
   346 	}
   347 }
   348 
   349 LoggingMode Logger::GetLoggingMode() const
   350 {
   351 	return m_mode;
   352 }
   353 
   354 void Logger::EnableLogging()
   355 {
   356 	if (m_Active)
   357 	{
   358 		return;
   359 	}
   360 	m_Active = true;
   361 	LogMessage("Logging enabled manually by user.");
   362 }
   363 
   364 void Logger::DisableLogging()
   365 {
   366 	if (!m_Active)
   367 	{
   368 		return;
   369 	}
   370 	LogMessage("Logging disabled manually by user.");
   371 	m_Active = false;
   372 }