/* Copyright (c) 2019 The Linux Foundation. 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. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * 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 "LogBuffer.h" #include #define LOG_TAG "LocSvc_LogBuffer" namespace loc_util { LogBuffer* LogBuffer::mInstance; struct sigaction LogBuffer::mOriSigAction[NSIG]; struct sigaction LogBuffer::mNewSigAction; mutex LogBuffer::sLock; LogBuffer* LogBuffer::getInstance() { if (mInstance == nullptr) { lock_guard guard(sLock); if (mInstance == nullptr) { mInstance = new LogBuffer(); } } return mInstance; } LogBuffer::LogBuffer(): mLogList(TOTAL_LOG_LEVELS), mConfigVec(TOTAL_LOG_LEVELS, ConfigsInLevel(TIME_DEPTH_THRESHOLD_MINIMAL_IN_SEC, MAXIMUM_NUM_IN_LIST, 0)) { loc_param_s_type log_buff_config_table[] = { {"E_LEVEL_TIME_DEPTH", &mConfigVec[0].mTimeDepthThres, NULL, 'n'}, {"E_LEVEL_MAX_CAPACITY", &mConfigVec[0].mMaxNumThres, NULL, 'n'}, {"W_LEVEL_TIME_DEPTH", &mConfigVec[1].mTimeDepthThres, NULL, 'n'}, {"W_LEVEL_MAX_CAPACITY", &mConfigVec[1].mMaxNumThres, NULL, 'n'}, {"I_LEVEL_TIME_DEPTH", &mConfigVec[2].mTimeDepthThres, NULL, 'n'}, {"I_LEVEL_MAX_CAPACITY", &mConfigVec[2].mMaxNumThres, NULL, 'n'}, {"D_LEVEL_TIME_DEPTH", &mConfigVec[3].mTimeDepthThres, NULL, 'n'}, {"D_LEVEL_MAX_CAPACITY", &mConfigVec[3].mMaxNumThres, NULL, 'n'}, {"V_LEVEL_TIME_DEPTH", &mConfigVec[4].mTimeDepthThres, NULL, 'n'}, {"V_LEVEL_MAX_CAPACITY", &mConfigVec[4].mMaxNumThres, NULL, 'n'}, }; loc_read_conf(LOC_PATH_GPS_CONF_STR, log_buff_config_table, sizeof(log_buff_config_table)/sizeof(log_buff_config_table[0])); registerSignalHandler(); } void LogBuffer::append(string& data, int level, uint64_t timestamp) { lock_guard guard(mLock); pair item(timestamp, data); mLogList.append(item, level); mConfigVec[level].mCurrentSize++; while ((timestamp - mLogList.front(level).first) > mConfigVec[level].mTimeDepthThres || mConfigVec[level].mCurrentSize > mConfigVec[level].mMaxNumThres) { mLogList.pop(level); mConfigVec[level].mCurrentSize--; } } //Dump the log buffer of specific level, level = -1 to dump all the levels in log buffer. void LogBuffer::dump(std::function log, int level) { lock_guard guard(mLock); list, int>> li; if (-1 == level) { li = mLogList.dump(); } else { li = mLogList.dump(level); } ALOGE("Begining of dump, buffer size: %d", (int)li.size()); stringstream ln; ln << "dump log buffer, level[" << level << "]" << ", buffer size: " << li.size() << endl; log(ln); for_each (li.begin(), li.end(), [&, this](const pair, int> &item){ stringstream line; line << "["<dumpToAdbLogcat(); //Dump the log buffer to file time_t now = time(NULL); struct tm *curr_time = localtime(&now); char path[50]; snprintf(path, 50, LOG_BUFFER_FILE_PATH "gpslog_%d%d%d-%d%d%d.log", (1900 + curr_time->tm_year), ( 1 + curr_time->tm_mon), curr_time->tm_mday, curr_time->tm_hour, curr_time->tm_min, curr_time->tm_sec); mInstance->dumpToLogFile(path); //Process won't be terminated if SIGUSR1 is recieved if (code != SIGUSR1) { mOriSigAction[code].sa_sigaction(code, si, sc); } } }