/* * Copyright (c) 2013-2015, dennis wang * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include "klogger/interface/logger.h" #include "pattern.h" #include "util.h" using namespace klogger; Pattern::Pattern() { _needTime = false; _needThreadId = false; _needProcessId = false; } Pattern::Pattern(const std::string &pattern) { _needTime = false; _needThreadId = false; _needProcessId = false; parse(pattern); } Pattern::~Pattern() { _needTime = false; _needThreadId = false; _needProcessId = false; } void Pattern::parse(const std::string &pattern) { _pattern.clear(); std::string::const_iterator iterator = pattern.begin(); bool holder = false; std::string result; for (; iterator != pattern.end(); iterator++) { if (*iterator == DELIM) { if (holder) { throw LoggerException("invalid pattern"); } holder = true; if (!result.empty()) { _pattern.push_back(result); result = ""; } } else { if (!holder) { result += *iterator; } else { if (!valid(*iterator)) { throw LoggerException("invalid pattern"); } if (hasTime(*iterator)) { _needTime = true; } else if (hasThread(*iterator)) { _needThreadId = true; } else if (hasProcess(*iterator)) { _needProcessId = true; } result += '%'; result += *iterator; _pattern.push_back(result); result = ""; holder = false; } } } if (!result.empty()) { _pattern.push_back(result); } } bool Pattern::valid(char p) { switch (p) { case TRHEAD_ID: case YEAR: case MONTH: case DAY: case HOUR: case MINUTE: case SECOND: case MILLI: case PROCESS: return true; } return false; } bool Pattern::hasProcess(char p) { switch (p) { case PROCESS: return true; } return false; } bool Pattern::hasThread(char p) { switch (p) { case TRHEAD_ID: return true; } return false; } bool Pattern::hasTime(char p) { switch (p) { case YEAR: case MONTH: case DAY: case HOUR: case MINUTE: case SECOND: case MILLI: return true; } return false; } std::string Pattern::getPrefix() { std::stringstream prefix; std::list::iterator iterator = _pattern.begin(); timeval tp; tm t; memset(&tp, 0, sizeof(timeval)); memset(&t, 0, sizeof(tm)); #if defined(_WIN32) || defined(WIN32) || defined(_WIN64) DWORD pid = 0; DWORD tid = 0; #else pid_t pid = 0; pthread_t tid = 0; #endif // _WIN32 if (_needTime) { getDateTime(&tp, &t); } if (_needThreadId) { #if defined(_WIN32) || defined(WIN32) || defined(_WIN64) tid = GetCurrentThreadId(); #else tid = pthread_self(); #endif // _WIN32 } if (_needProcessId) { #if defined(_WIN32) || defined(WIN32) || defined(_WIN64) pid = GetCurrentProcessId(); #else tid = getpid(); #endif // _WIN32 } for (; iterator != _pattern.end(); iterator++) { if (DELIM != iterator->at(0)) { prefix << *iterator; } else { char mode = iterator->at(1); switch (mode) { case YEAR: prefix << t.tm_year + 1900; break; case MONTH: if (t.tm_mon + 1 < 10) { prefix << "0"; } prefix << t.tm_mon + 1; break; case DAY: if (t.tm_mday < 10) { prefix << "0"; } prefix << t.tm_mday; break; case HOUR: if (t.tm_hour < 10) { prefix << "0"; } prefix << t.tm_hour; break; case MINUTE: if (t.tm_min < 10) { prefix << "0"; } prefix << t.tm_min; break; case SECOND: if (t.tm_sec < 10) { prefix << "0"; } prefix << t.tm_sec; break; case MILLI: { long usec = tp.tv_usec / 1000; if (usec < 10) { prefix << "0"; } if (usec < 100) { prefix << "0"; } prefix << usec; } break; case TRHEAD_ID: prefix << tid; break; case PROCESS: prefix << pid; break; default: throw LoggerException("invalid pattern"); } } } return prefix.str(); } std::string Pattern::getTime() { std::stringstream prefix; std::list::iterator iterator = _pattern.begin(); timeval tp; tm t; memset(&tp, 0, sizeof(timeval)); memset(&t, 0, sizeof(tm)); if (_needTime) { getDateTime(&tp, &t); } for (; iterator != _pattern.end(); iterator++) { if (DELIM != iterator->at(0)) { prefix << *iterator; } else { char mode = iterator->at(1); switch (mode) { case YEAR: prefix << t.tm_year + 1900; break; case MONTH: if (t.tm_mon + 1 < 10) { prefix << "0"; } prefix << t.tm_mon + 1; break; case DAY: if (t.tm_mday < 10) { prefix << "0"; } prefix << t.tm_mday; break; case HOUR: if (t.tm_hour < 10) { prefix << "0"; } prefix << t.tm_hour; break; case MINUTE: if (t.tm_min < 10) { prefix << "0"; } prefix << t.tm_min; break; case SECOND: if (t.tm_sec < 10) { prefix << "0"; } prefix << t.tm_sec; break; case MILLI: { long usec = tp.tv_usec / 1000; if (usec < 10) { prefix << "0"; } if (usec < 100) { prefix << "0"; } prefix << usec; } break; case TRHEAD_ID: case PROCESS: break; default: throw LoggerException("invalid pattern"); } } } return prefix.str(); }