ED247 Library  VA2.3.0
Implementation of ED247-A standard
ed247_logs.h
1 /* -*- mode: c++; c-basic-offset: 2 -*- */
2 /******************************************************************************
3  * The MIT Licence
4  *
5  * Copyright (c) 2021 Airbus Operations S.A.S
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a
8  * copy of this software and associated documentation files (the "Software"),
9  * to deal in the Software without restriction, including without limitation
10  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11  * and/or sell copies of the Software, and to permit persons to whom the
12  * Software is furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included
15  * in all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23  * OTHER DEALINGS IN THE SOFTWARE.
24  *****************************************************************************/
25 #ifndef _ED247_LOGS_H_
26 #define _ED247_LOGS_H_
27 #include "ed247.h"
28 #include "ed247_friend_test.h"
29 #include <string.h>
30 #include <sstream>
31 #include <iostream>
32 #include <fstream>
33 #include <exception>
34 
35 // Prefix traces by file:line
36 #define LOG_SHORTFILE (strrchr("/" __FILE__, '/') + 1)
37 #define LOG_STREAM_FILELINE LOG_SHORTFILE << ":" << __LINE__ << " "
38 
39 // Print a trace regardless log level
40 #define SAY(m) do { SAY_STREAM(ED247_LOG_STREAM, m); } while (0)
41 
42 // Print a trace depending on log level
43 #define PRINT_ERROR(m) do { if (ED247_LOG_ENABLED(ED247_LOG_LEVEL_ERROR)) ED247_LOG_STREAM << LOG_STREAM_FILELINE << "[ERROR] " << m << std::endl; } while (0)
44 #define PRINT_WARNING(m) do { if (ED247_LOG_ENABLED(ED247_LOG_LEVEL_WARNING)) ED247_LOG_STREAM << LOG_STREAM_FILELINE << "[WARN] " << m << std::endl; } while (0)
45 #define PRINT_INFO(m) do { if (ED247_LOG_ENABLED(ED247_LOG_LEVEL_INFO)) ED247_LOG_STREAM << LOG_STREAM_FILELINE << m << std::endl; } while (0)
46 #define PRINT_DEBUG(m) do { if (ED247_LOG_ENABLED(ED247_LOG_LEVEL_DEBUG)) ED247_LOG_STREAM << LOG_STREAM_FILELINE << m << std::endl; } while (0)
47 #define PRINT_CRAZY(m) do { if (ED247_LOG_ENABLED(ED247_LOG_LEVEL_CRAZY)) ED247_LOG_STREAM << LOG_STREAM_FILELINE << m << std::endl; } while (0)
48 
49 #ifdef SIMULINK_LOGGER_ENABLED
50 # include "Logger.hpp"
51 # define ED247_LOG_STREAM LOG(info, 0)
52 #else
53 # define ED247_LOG_STREAM ed247::log::get().stream()
54 #endif
55 
56 #define ED247_LOG_ENABLED(level) ed247::log::get().enabled(level)
57 #define SAY_STREAM(stream, m) do { (stream) << LOG_STREAM_FILELINE << m << std::endl; } while (0)
58 
59 // Logger internals
60 namespace ed247 {
61  struct LIBED247_EXPORT log
62  {
63  static constexpr const char* ENV_VAR_LEVEL = "ED247_LOG_LEVEL";
64  static constexpr const char* ENV_VAR_FILEPATH = "ED247_LOG_FILEPATH";
65 
66  // Get the logger. May create it (see reset()).
67  static log& get() { return *((_logger)? _logger : create_logger()); }
68 
69  // Change logger parameters.
70  // Defaut values are ED247_LOG_LEVEL_DEFAULT and std::cerr.
71  // The env variables have always the priority (see ENV_VAR_*).
72  void reset(ed247_log_level_t level = ED247_LOG_LEVEL_DEFAULT, const char* filepath = nullptr);
73 
74  // Return the stream to write to.
75  std::ostream& stream() { return (_fstream.is_open())? _fstream : std::cerr; }
76 
77  // Return the log level.
78  ed247_log_level_t level() { return get()._level; }
79 
80  // Return true if log is enabled at `level'
81  bool enabled(ed247_log_level_t level) { return _level >= level; }
82 
83  // Convert `level' to a string
84  static std::string level_name(ed247_log_level_t level);
85 
86  private:
87  static log* create_logger();
88  static void delete_logger();
89 
90  log() : _level(ED247_LOG_LEVEL_UNSET) { reset(); }
91  ~log();
92  void set_level(ed247_log_level_t level);
93 
94  static log* _logger;
95  ed247_log_level_t _level;
96  std::ofstream _fstream;
97  std::string _filepath;
98 
99  ED247_FRIEND_TEST();
100  };
101 }
102 
103 // Generate a backtrace (if supported)
104 extern LIBED247_EXPORT void ed247_log_backtrace();
105 
106 // ED247 exception
107 namespace ed247 {
108  class exception : public std::exception
109  {
110  public:
111  exception(std::string message) : _message (message) {};
112  virtual ~exception() throw () override {}
113  inline const char* what() const noexcept override { return _message.c_str(); }
114  private:
115  std::string _message;
116  };
117 }
118 #define THROW_ED247_ERROR(message) \
119  do { \
120  PRINT_ERROR(message); \
121  throw ed247::exception(strize() << message); \
122  } while(0)
123 
124 
125 // ED247 enums to stream
126 inline std::ostream& operator<<(std::ostream& stream, const ed247_log_level_t& level) { return (stream << ed247::log::level_name(level)); }
127 inline std::ostream& operator<<(std::ostream& stream, const ed247_status_t& status) { return (stream << ed247_status_string(status)); }
128 inline std::ostream& operator<<(std::ostream& stream, const ed247_direction_t& direction) { return (stream << ed247_direction_string(direction)); }
129 inline std::ostream& operator<<(std::ostream& stream, const ed247_stream_type_t& stype) { return (stream << ed247_stream_type_string(stype)); }
130 inline std::ostream& operator<<(std::ostream& stream, const ed247_signal_type_t& stype) { return (stream << ed247_signal_type_string(stype)); }
131 inline std::ostream& operator<<(std::ostream& stream, const ed247_nad_type_t& ntype) { return (stream << ed247_nad_type_string(ntype)); }
132 
133 
134 // Memcheck
135 //#define ENABLE_MEMCHECK
136 #ifdef ENABLE_MEMCHECK
137 namespace ed247 {
138  namespace memcheck {
139  void add(const void* ptr, std::string title);
140  void remove(const void* ptr);
141  void assert_freed();
142  void free();
143  }
144 }
145 #define MEMCHECK_SAY(ptr, m) SAY("[MEMCHECK " << ptr << "] " << m)
146 #define MEMCHECK_NEW(ptr, title) do { MEMCHECK_SAY(ptr, "NEW " << title); ed247::memcheck::add(ptr, strize() << title); } while (0)
147 #define MEMCHECK_DEL(ptr, title) do { MEMCHECK_SAY(ptr, "DEL " << title); ed247::memcheck::remove(ptr); } while (0)
148 #define MEMCHECK_FREED() ed247::memcheck::assert_freed()
149 #define MEMCHECK_RESET() ed247::memcheck::free()
150 #else
151 #define MEMCHECK_SAY(ptr, m)
152 #define MEMCHECK_NEW(ptr, title)
153 #define MEMCHECK_DEL(ptr, title)
154 #define MEMCHECK_FREED()
155 #define MEMCHECK_RESET()
156 #endif
157 
158 
159 
160 // Helper to create a string from stream: std::string foo = strize() << "hello " << 42;
161 struct strize {
162  template<typename T> strize& operator<<(T value) { _content << value; return *this; }
163  operator std::string() const { return _content.str(); }
164 private:
165  std::stringstream _content;
166 };
167 
168 
169 // Helper to convert a payload to hexa stream: stream << "data: " << hex_stream(data, 4) << std::endl;
171 {
172 public:
173  hex_stream(const void* payload, int len) : _payload((const uint8_t*)payload), _len(len) {}
174  LIBED247_EXPORT friend std::ostream& operator<<(std::ostream& stream, const hex_stream&);
175 private:
176  const uint8_t* _payload;
177  int _len;
178 };
179 
180 #endif
Definition: ed247_logs.h:161
LIBED247_EXPORT const char * ed247_stream_type_string(ed247_stream_type_t stream_type)
ed247_stream_type_t to string conversion
Definition: ed247_conversion.cpp:188
Definition: ed247_logs.h:170
LIBED247_EXPORT const char * ed247_status_string(ed247_status_t status)
ed247_status_t to string conversion
Definition: ed247_conversion.cpp:80
LIBED247_EXPORT const char * ed247_signal_type_string(ed247_signal_type_t signal_type)
ed247_signal_type_t to string conversion
Definition: ed247_conversion.cpp:241
ed247_direction_t
Stream direction.
Definition: ed247.h:153
Definition: ed247_logs.h:108
ed247_signal_type_t
Signal types.
Definition: ed247.h:164
LIBED247_EXPORT const char * ed247_nad_type_string(ed247_nad_type_t nad_type)
ed247_nad_type_t to string conversion
Definition: ed247_conversion.cpp:270
LIBED247_EXPORT const char * ed247_direction_string(ed247_direction_t direction)
ed247_direction_t to string conversion
Definition: ed247_conversion.cpp:102
ed247_nad_type_t
NAD type.
Definition: ed247.h:176
ed247_log_level_t
Logging level.
Definition: ed247.h:78
ed247_status_t
Status codes.
Definition: ed247.h:67
Definition: ed247_channel.cpp:37
ed247_stream_type_t
Stream types.
Definition: ed247.h:132
Definition: ed247_logs.h:61