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