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