LCOV - code coverage report
Current view: top level - nntrainer - nntrainer_logger.cpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 85.1 % 67 57
Test Date: 2025-12-14 20:38:17 Functions: 100.0 % 7 7

            Line data    Source code
       1              : /**
       2              :  * Copyright (C) 2020 Samsung Electronics Co., Ltd. All Rights Reserved.
       3              :  *
       4              :  * Licensed under the Apache License, Version 2.0 (the "License");
       5              :  * you may not use this file except in compliance with the License.
       6              :  * You may obtain a copy of the License at
       7              :  *   http://www.apache.org/licenses/LICENSE-2.0
       8              :  * Unless required by applicable law or agreed to in writing, software
       9              :  * distributed under the License is distributed on an "AS IS" BASIS,
      10              :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      11              :  * See the License for the specific language governing permissions and
      12              :  * limitations under the License.
      13              :  */
      14              : /**
      15              :  * @file nntrainer_logger.cpp
      16              :  * @date 02 April 2020
      17              :  * @brief NNTrainer Logger
      18              :  *        This allows to logging nntrainer logs.
      19              :  * @see https://github.com/nnstreamer/nntrainer
      20              :  * @author Jijoong Moon <jijoong.moon@samsung.com>
      21              :  * @bug No known bugs except for NYI items
      22              :  */
      23              : 
      24              : #include <cstring>
      25              : #include <ctime>
      26              : #include <filesystem>
      27              : #include <iomanip>
      28              : #include <iostream>
      29              : #include <mutex>
      30              : #include <nntrainer_logger.h>
      31              : #include <sstream>
      32              : #include <stdarg.h>
      33              : #include <stdexcept>
      34              : #include <util_func.h>
      35              : 
      36              : namespace nntrainer {
      37              : 
      38              : /**
      39              :  * @brief     logfile name
      40              :  */
      41              : const char *const Logger::logfile_name = "log_nntrainer_";
      42              : const char *const Logger::logfile_dir = "./logs/";
      43              : /**
      44              :  * @brief     instance for single logger
      45              :  */
      46              : Logger *Logger::ainstance = nullptr;
      47              : 
      48              : /**
      49              :  * @brief     mutex for lock
      50              :  */
      51              : std::mutex Logger::smutex;
      52              : 
      53        56734 : Logger &Logger::instance() {
      54        56734 :   static Cleanup cleanup;
      55              : 
      56              :   std::lock_guard<std::mutex> guard(smutex);
      57        56734 :   if (ainstance == nullptr)
      58           30 :     ainstance = new Logger();
      59        56734 :   return *ainstance;
      60              : }
      61              : 
      62           30 : Logger::Cleanup::~Cleanup() {
      63              :   std::lock_guard<std::mutex> guard(Logger::smutex);
      64           30 :   delete Logger::ainstance;
      65           30 :   Logger::ainstance = nullptr;
      66           30 : }
      67              : 
      68           60 : Logger::~Logger() {
      69              :   try {
      70           30 :     outputstream.close();
      71            0 :   } catch (...) {
      72            0 :     std::cerr << "Error closing the log file\n";
      73            0 :   }
      74           60 : }
      75              : 
      76           30 : Logger::Logger() : ts_type(NNTRAINER_LOG_TIMESTAMP_SEC) {
      77              :   struct tm now;
      78           30 :   getLocaltime(&now);
      79           30 :   std::stringstream ss;
      80           30 :   ss << logfile_name << std::dec << (now.tm_year + 1900) << std::setfill('0')
      81           60 :      << std::setw(2) << (now.tm_mon + 1) << std::setfill('0') << std::setw(2)
      82           30 :      << now.tm_mday << std::setfill('0') << std::setw(2) << now.tm_hour
      83           30 :      << std::setfill('0') << std::setw(2) << now.tm_min << std::setfill('0')
      84           60 :      << std::setw(2) << now.tm_sec << ".out";
      85           60 :   if (!std::filesystem::exists(logfile_dir)) {
      86            1 :     std::filesystem::create_directories(logfile_dir);
      87              :   }
      88           60 :   outputstream.open(logfile_dir + ss.str(), std::ios_base::app);
      89           30 :   if (!outputstream.good()) {
      90            0 :     char buf[256] = {
      91              :       0,
      92              :     };
      93            0 :     std::string cur_path = std::string(buf);
      94              :     std::string err_msg =
      95            0 :       "Unable to initialize the Logger on path(" + cur_path + ")";
      96            0 :     throw std::runtime_error(err_msg);
      97              :   }
      98           30 : }
      99              : 
     100        56734 : void Logger::log(const std::string &message,
     101              :                  const nntrainer_loglevel loglevel) {
     102              :   std::lock_guard<std::mutex> guard(smutex);
     103        56734 :   std::stringstream ss;
     104              : 
     105        56734 :   switch (loglevel) {
     106        14434 :   case NNTRAINER_LOG_INFO:
     107        14434 :     ss << "[NNTRAINER INFO  ";
     108              :     break;
     109         1922 :   case NNTRAINER_LOG_WARN:
     110         1922 :     ss << "[NNTRAINER WARN  ";
     111              :     break;
     112          788 :   case NNTRAINER_LOG_ERROR:
     113          788 :     ss << "[NNTRAINER ERROR ";
     114              :     break;
     115        39590 :   case NNTRAINER_LOG_DEBUG:
     116        39590 :     ss << "[NNTRAINER DEBUG ";
     117              :     break;
     118              :   default:
     119              :     break;
     120              :   }
     121              : 
     122        56734 :   if (ts_type == NNTRAINER_LOG_TIMESTAMP_MS) {
     123            0 :     static auto start = std::chrono::system_clock::now().time_since_epoch();
     124              :     auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
     125            0 :                 std::chrono::system_clock::now().time_since_epoch() - start)
     126              :                 .count();
     127              : 
     128            0 :     ss << "[ " << ms << " ]";
     129        56734 :   } else if (ts_type == NNTRAINER_LOG_TIMESTAMP_SEC) {
     130              :     struct tm now;
     131        56734 :     getLocaltime(&now);
     132              : 
     133        56734 :     ss << std::dec << (now.tm_year + 1900) << '-' << std::setfill('0')
     134        56734 :        << std::setw(2) << (now.tm_mon + 1) << '-' << std::setfill('0')
     135        56734 :        << std::setw(2) << now.tm_mday << ' ' << std::setfill('0')
     136        56734 :        << std::setw(2) << now.tm_hour << ':' << std::setfill('0')
     137       113468 :        << std::setw(2) << now.tm_min << ':' << std::setfill('0') << std::setw(2)
     138        56734 :        << now.tm_sec << ']';
     139              :   }
     140              : 
     141        56734 :   outputstream << ss.str() << " " << message << std::endl;
     142       113468 : }
     143              : 
     144              : } /* namespace nntrainer */
     145              : 
     146              : #ifdef __cplusplus
     147              : extern "C" {
     148              : #endif
     149        56734 : void __nntrainer_log_print(nntrainer_loglevel loglevel,
     150              :                            const std::string format_str, ...) {
     151        56734 :   int final_n, n = ((int)format_str.size()) * 2;
     152              :   std::unique_ptr<char[]> formatted;
     153              :   va_list ap;
     154              :   while (1) {
     155       113071 :     formatted.reset(new char[n]);
     156              :     std::strncpy(&formatted[0], format_str.c_str(), format_str.size());
     157       113071 :     va_start(ap, format_str);
     158              :     final_n = vsnprintf(&formatted[0], n, format_str.c_str(), ap);
     159       113071 :     va_end(ap);
     160       113071 :     if (final_n < 0 || final_n >= n)
     161        56337 :       n += abs(final_n - n + 1);
     162              :     else
     163              :       break;
     164              :   }
     165              : 
     166        56734 :   std::string ss = std::string(formatted.get());
     167              : 
     168              : #if defined(__LOGGING__)
     169        56734 :   nntrainer::Logger::instance().log(ss, loglevel);
     170              : #else
     171              : 
     172              : #if defined(DEBUG)
     173              :   switch (loglevel) {
     174              :   case NNTRAINER_LOG_ERROR:
     175              :     std::cerr << ss << std::endl;
     176              :     break;
     177              :   case NNTRAINER_LOG_INFO:
     178              :   case NNTRAINER_LOG_WARN:
     179              :   case NNTRAINER_LOG_DEBUG:
     180              :     std::cout << ss << std::endl;
     181              :   default:
     182              :     break;
     183              :   }
     184              : #endif
     185              : #endif
     186        56734 : }
     187              : 
     188              : #ifdef __cplusplus
     189              : }
     190              : #endif
        

Generated by: LCOV version 2.0-1