LCOV - code coverage report
Current view: top level - wirestead/diagnostics - error_types.hpp (source / functions) Coverage Total Hit
Test: Wirestead Coverage Report Lines: 97.4 % 78 76
Test Date: 2026-08-30 10:35:09 Functions: 100.0 % 8 8
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 85.0 % 20 17

             Branch data     Line data    Source code
       1                 :             : /*
       2                 :             :  * Copyright 2025 Jinwoo Sung
       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                 :             :  *
       8                 :             :  *     http://www.apache.org/licenses/LICENSE-2.0
       9                 :             :  *
      10                 :             :  * Unless required by applicable law or agreed to in writing, software
      11                 :             :  * distributed under the License is distributed on an "AS IS" BASIS,
      12                 :             :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      13                 :             :  * See the License for the specific language governing permissions and
      14                 :             :  * limitations under the License.
      15                 :             :  */
      16                 :             : 
      17                 :             : #pragma once
      18                 :             : 
      19                 :             : #include <algorithm>
      20                 :             : #include <boost/system/error_code.hpp>
      21                 :             : #include <chrono>
      22                 :             : #include <cstdint>
      23                 :             : #include <ctime>
      24                 :             : #include <iomanip>
      25                 :             : #include <sstream>
      26                 :             : #include <string>
      27                 :             : #include <string_view>
      28                 :             : 
      29                 :             : namespace wirestead {
      30                 :             : namespace diagnostics {
      31                 :             : 
      32                 :             : #ifdef ERROR
      33                 :             : #undef ERROR
      34                 :             : #endif
      35                 :             : #ifdef WARNING
      36                 :             : #undef WARNING
      37                 :             : #endif
      38                 :             : 
      39                 :             : /**
      40                 :             :  * @brief Error severity levels
      41                 :             :  */
      42                 :             : enum class ErrorLevel {
      43                 :             :   INFO = 0,     // Informational message (normal operation info)
      44                 :             :   WARNING = 1,  // Warning (recoverable issue)
      45                 :             :   ERROR = 2,    // Error (retry required)
      46                 :             :   CRITICAL = 3  // Critical error (unrecoverable)
      47                 :             : };
      48                 :             : 
      49                 :             : /**
      50                 :             :  * @brief Error categories for classification
      51                 :             :  */
      52                 :             : enum class ErrorCategory {
      53                 :             :   CONNECTION = 0,     // Connection related (TCP, Serial connect/disconnect)
      54                 :             :   COMMUNICATION = 1,  // Communication related (data send/receive)
      55                 :             :   CONFIGURATION = 2,  // Configuration related (invalid config values)
      56                 :             :   MEMORY = 3,         // Memory related (allocation/deallocation errors)
      57                 :             :   SYSTEM = 4,         // System related (OS level errors)
      58                 :             :   UNKNOWN = 5         // Unknown error
      59                 :             : };
      60                 :             : 
      61                 :             : /**
      62                 :             :  * @brief Comprehensive error information structure
      63                 :             :  */
      64                 :             : struct ErrorInfo {
      65                 :             :   ErrorLevel level;                                 // Error severity
      66                 :             :   ErrorCategory category;                           // Error category
      67                 :             :   std::string component;                            // Component name (serial, tcp_server, tcp_client)
      68                 :             :   std::string operation;                            // Operation being performed (read, write, connect, bind)
      69                 :             :   std::string message;                              // Error message
      70                 :             :   boost::system::error_code boost_error;            // Boost error code
      71                 :             :   std::chrono::system_clock::time_point timestamp;  // Error occurrence time
      72                 :             :   bool retryable;                                   // Retry possibility
      73                 :             :   uint32_t retry_count;                             // Current retry count
      74                 :             :   std::string context;                              // Additional context information
      75                 :             : 
      76                 :             :   /**
      77                 :             :    * @brief Constructor for basic error info
      78                 :             :    */
      79                 :        1045 :   ErrorInfo(ErrorLevel l, ErrorCategory c, std::string_view comp, std::string_view op, std::string_view msg)
      80                 :        1045 :       : level(l),
      81                 :        1045 :         category(c),
      82                 :        2090 :         component(comp),
      83                 :        2090 :         operation(op),
      84                 :        2090 :         message(msg),
      85                 :        1045 :         timestamp(std::chrono::system_clock::now()),
      86                 :        1045 :         retryable(false),
      87                 :        2090 :         retry_count(0) {}
      88                 :             : 
      89                 :             :   /**
      90                 :             :    * @brief Constructor with Boost error code
      91                 :             :    */
      92                 :         281 :   ErrorInfo(ErrorLevel l, ErrorCategory c, std::string_view comp, std::string_view op, std::string_view msg,
      93                 :             :             const boost::system::error_code& ec, bool retry = false)
      94                 :         281 :       : level(l),
      95                 :         281 :         category(c),
      96                 :         562 :         component(comp),
      97                 :         562 :         operation(op),
      98                 :         562 :         message(msg),
      99                 :         281 :         boost_error(ec),
     100                 :         281 :         timestamp(std::chrono::system_clock::now()),
     101                 :         281 :         retryable(retry),
     102                 :         281 :         retry_count(0) {}
     103                 :             : 
     104                 :             :   /**
     105                 :             :    * @brief Get formatted timestamp string
     106                 :             :    */
     107                 :           1 :   std::string timestamp_string() const {
     108                 :           1 :     auto time_t = std::chrono::system_clock::to_time_t(timestamp);
     109                 :           1 :     auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(timestamp.time_since_epoch()) % 1000;
     110                 :             : 
     111                 :           1 :     std::tm tm_buf{};
     112                 :             : #if defined(_MSC_VER)
     113                 :             :     localtime_s(&tm_buf, &time_t);
     114                 :             : #else
     115                 :           1 :     localtime_r(&time_t, &tm_buf);
     116                 :             : #endif
     117                 :             : 
     118                 :           1 :     std::ostringstream oss;
     119                 :           1 :     oss << std::put_time(&tm_buf, "%Y-%m-%d %H:%M:%S");
     120                 :           1 :     oss << '.' << std::setfill('0') << std::setw(3) << ms.count();
     121                 :           2 :     return oss.str();
     122                 :           1 :   }
     123                 :             : 
     124                 :             :   /**
     125                 :             :    * @brief Get error level as string
     126                 :             :    */
     127                 :           9 :   std::string level_string() const {
     128   [ +  +  +  +  :           9 :     switch (level) {
                      - ]
     129                 :           1 :       case ErrorLevel::INFO:
     130                 :           2 :         return "INFO";
     131                 :           1 :       case ErrorLevel::WARNING:
     132                 :           2 :         return "WARNING";
     133                 :           3 :       case ErrorLevel::ERROR:
     134                 :           6 :         return "ERROR";
     135                 :           4 :       case ErrorLevel::CRITICAL:
     136                 :           8 :         return "CRITICAL";
     137                 :             :     }
     138                 :           0 :     return "UNKNOWN";
     139                 :             :   }
     140                 :             : 
     141                 :             :   /**
     142                 :             :    * @brief Get error category as string
     143                 :             :    */
     144                 :           7 :   std::string category_string() const {
     145   [ +  +  +  +  :           7 :     switch (category) {
                +  +  - ]
     146                 :           1 :       case ErrorCategory::CONNECTION:
     147                 :           2 :         return "CONNECTION";
     148                 :           2 :       case ErrorCategory::COMMUNICATION:
     149                 :           4 :         return "COMMUNICATION";
     150                 :           1 :       case ErrorCategory::CONFIGURATION:
     151                 :           2 :         return "CONFIGURATION";
     152                 :           1 :       case ErrorCategory::MEMORY:
     153                 :           2 :         return "MEMORY";
     154                 :           1 :       case ErrorCategory::SYSTEM:
     155                 :           2 :         return "SYSTEM";
     156                 :           1 :       case ErrorCategory::UNKNOWN:
     157                 :           2 :         return "UNKNOWN";
     158                 :             :     }
     159                 :           0 :     return "UNKNOWN";
     160                 :             :   }
     161                 :             : 
     162                 :             :   /**
     163                 :             :    * @brief Get formatted error summary
     164                 :             :    */
     165                 :           3 :   std::string summary() const {
     166                 :           3 :     std::ostringstream oss;
     167                 :           3 :     oss << "[" << level_string() << "] " << "[" << component << "] " << "[" << operation << "] " << message;
     168                 :             : 
     169         [ +  + ]:           3 :     if (boost_error) {
     170                 :           2 :       oss << " (boost: " << boost_error.message() << ", code: " << boost_error.value() << ")";
     171                 :             :     }
     172                 :             : 
     173         [ +  + ]:           3 :     if (retryable) {
     174                 :           2 :       oss << " [RETRYABLE, count: " << retry_count << "]";
     175                 :             :     }
     176                 :             : 
     177                 :           6 :     return oss.str();
     178                 :           3 :   }
     179                 :             : };
     180                 :             : 
     181                 :             : /**
     182                 :             :  * @brief Error statistics for monitoring
     183                 :             :  */
     184                 :             : struct ErrorStats {
     185                 :             :   size_t total_errors = 0;
     186                 :             :   size_t errors_by_level[4] = {0, 0, 0, 0};           // INFO, WARNING, ERROR, CRITICAL
     187                 :             :   size_t errors_by_category[6] = {0, 0, 0, 0, 0, 0};  // CONNECTION, COMMUNICATION, etc.
     188                 :             :   size_t retryable_errors = 0;
     189                 :             :   size_t successful_retries = 0;
     190                 :             :   size_t failed_retries = 0;
     191                 :             : 
     192                 :             :   std::chrono::system_clock::time_point first_error;
     193                 :             :   std::chrono::system_clock::time_point last_error;
     194                 :             : 
     195                 :             :   /**
     196                 :             :    * @brief Reset all statistics
     197                 :             :    */
     198                 :          24 :   void reset() {
     199                 :          24 :     total_errors = 0;
     200                 :          72 :     std::fill(std::begin(errors_by_level), std::end(errors_by_level), 0);
     201                 :          72 :     std::fill(std::begin(errors_by_category), std::end(errors_by_category), 0);
     202                 :          24 :     retryable_errors = 0;
     203                 :          24 :     successful_retries = 0;
     204                 :          24 :     failed_retries = 0;
     205                 :          24 :     first_error = std::chrono::system_clock::time_point{};
     206                 :          24 :     last_error = std::chrono::system_clock::time_point{};
     207                 :          24 :   }
     208                 :             : 
     209                 :             :   /**
     210                 :             :    * @brief Get error rate (errors per minute)
     211                 :             :    */
     212                 :           2 :   double error_rate() const {
     213         [ +  + ]:           2 :     if (total_errors == 0) return 0.0;
     214                 :             : 
     215                 :           1 :     auto duration = std::chrono::duration_cast<std::chrono::minutes>(last_error - first_error).count();
     216         [ +  - ]:           1 :     return duration > 0 ? static_cast<double>(total_errors) / static_cast<double>(duration) : 0.0;
     217                 :             :   }
     218                 :             : };
     219                 :             : 
     220                 :             : }  // namespace diagnostics
     221                 :             : }  // namespace wirestead
        

Generated by: LCOV version 2.0-1