pstore2
logging.hpp
Go to the documentation of this file.
1 //===- include/pstore/os/logging.hpp ----------------------*- mode: C++ -*-===//
2 //* _ _ *
3 //* | | ___ __ _ __ _(_)_ __ __ _ *
4 //* | |/ _ \ / _` |/ _` | | '_ \ / _` | *
5 //* | | (_) | (_| | (_| | | | | | (_| | *
6 //* |_|\___/ \__, |\__, |_|_| |_|\__, | *
7 //* |___/ |___/ |___/ *
8 //===----------------------------------------------------------------------===//
9 //
10 // Part of the pstore project, under the Apache License v2.0 with LLVM Exceptions.
11 // See https://github.com/SNSystems/pstore/blob/master/LICENSE.txt for license
12 // information.
13 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
14 //
15 //===----------------------------------------------------------------------===//
17 
18 #ifndef PSTORE_OS_LOGGING_HPP
19 #define PSTORE_OS_LOGGING_HPP
20 
21 #include <fstream>
22 #include <mutex>
23 
24 #include "pstore/os/file.hpp"
25 #include "pstore/os/thread.hpp"
26 
27 namespace pstore {
28 
29  //* _ *
30  //* | |___ __ _ __ _ ___ _ _ *
31  //* | / _ \/ _` / _` / -_) '_| *
32  //* |_\___/\__, \__, \___|_| *
33  //* |___/|___/ *
35  class logger {
36  public:
37  enum class priority {
38  emergency,
39  alert,
40  critical,
41  error,
42  warning,
43  notice,
44  info,
45  debug
46  };
47 
48  class quoted {
49  public:
50  constexpr explicit quoted (gsl::not_null<gsl::czstring> const str) noexcept
51  : str_{str} {}
52  constexpr explicit operator gsl::czstring () const noexcept { return str_; }
53 
54  private:
55  gsl::czstring str_;
56  };
57 
58  logger () = default;
59  logger (logger const &) = delete;
60  logger (logger &&) noexcept = delete;
61 
62  virtual ~logger () noexcept = default;
63 
64  logger & operator= (logger const &) = delete;
65  logger & operator= (logger &&) noexcept = delete;
66 
67  void set_priority (priority const p) noexcept { priority_ = p; }
68  priority get_priority () const noexcept { return priority_; }
69 
70  virtual void log (priority p, std::string const & message) = 0;
71 
72  virtual void log (priority p, gsl::czstring message, int d);
73  virtual void log (priority p, gsl::czstring message, unsigned d);
74  virtual void log (priority p, gsl::czstring message, long d);
75  virtual void log (priority p, gsl::czstring message, unsigned long d);
76  virtual void log (priority p, gsl::czstring message, long long d);
77  virtual void log (priority p, gsl::czstring message, unsigned long long d);
78 
79  virtual void log (priority p, gsl::czstring message);
80  virtual void log (priority p, gsl::czstring part1, gsl::czstring part2);
81  virtual void log (priority p, gsl::czstring part1, quoted part2);
82 
83  void log (priority const p, gsl::czstring const message, std::string const & d) {
84  this->log (p, message, d.c_str ());
85  }
86 
87  private:
88  template <typename T>
89  static std::string to_string (gsl::czstring const message, T const t) {
90  return message + std::to_string (t);
91  }
92 
93  std::string buffer_;
94  priority priority_ = priority::debug;
95  };
96 
97  //* _ _ _ *
98  //* | |__ __ _ __(_)__ | |___ __ _ __ _ ___ _ _ *
99  //* | '_ \/ _` (_-< / _| | / _ \/ _` / _` / -_) '_| *
100  //* |_.__/\__,_/__/_\__| |_\___/\__, \__, \___|_| *
101  //* |___/|___/ *
102  class basic_logger : public logger {
103  public:
104  basic_logger () = default;
105 
106  static gsl::czstring priority_string (priority p) noexcept;
107  static std::string get_current_thread_name ();
108 
109  static constexpr std::size_t const time_buffer_size = sizeof "YYYY-MM-DDTHH:mm:SS+ZZZZ";
110  static std::size_t time_string (std::time_t t,
111  gsl::span<char, time_buffer_size> const & buffer);
112 
113  using logger::log;
114  void log (priority p, std::string const & message) final;
115 
116  private:
117  virtual void log_impl (std::string const & message) = 0;
118 
119  static std::mutex mutex_;
120  std::string thread_name_ = get_current_thread_name ();
121  };
122 
123  //* _ *
124  //* _|_o| _ | _ _ _ _ ._ *
125  //* | ||(/_ |(_)(_|(_|(/_| *
126  //* _| _| *
127  class file_logger : public basic_logger {
128  protected:
129  explicit file_logger (FILE * const file)
130  : file_{file} {}
131 
132  private:
133  void log_impl (std::string const & message) override;
134  FILE * file_;
135  };
136 
137  //* *
138  //* __|_ _| _ _|_ | _ _ _ _ ._ *
139  //* _> |_(_|(_)|_||_ |(_)(_|(_|(/_| *
140  //* _| _| *
141  class stdout_logger final : public file_logger {
142  public:
143  stdout_logger ()
144  : file_logger{stdout} {}
145  stdout_logger (stdout_logger const &) = delete;
146  stdout_logger (stdout_logger &&) noexcept = delete;
147 
148  ~stdout_logger () noexcept override;
149 
150  stdout_logger & operator= (stdout_logger const &) = delete;
151  stdout_logger & operator= (stdout_logger &&) noexcept = delete;
152  };
153 
154  //* *
155  //* __|_ _| _ ._._ | _ _ _ _ ._ *
156  //* _> |_(_|(/_| | |(_)(_|(_|(/_| *
157  //* _| _| *
158  class stderr_logger final : public file_logger {
159  public:
160  stderr_logger ()
161  : file_logger{stderr} {}
162  stderr_logger (stderr_logger const &) = delete;
163  stderr_logger (stderr_logger &&) noexcept = delete;
164 
165  ~stderr_logger () noexcept override;
166 
167  stderr_logger & operator= (stderr_logger const &) = delete;
168  stderr_logger & operator= (stderr_logger &&) noexcept = delete;
169  };
170 
171 
172 
174  static bool exists (std::string const & path) { return pstore::file::exists (path); }
175  static void rename (std::string const & from, std::string const & to) {
177  f.rename (to);
178  }
179  static void unlink (std::string const & path) { pstore::file::unlink (path); }
180  };
181  struct fstream_traits {
182  using stream_type = std::ofstream;
183 
184  static void open (stream_type & s, std::string const & name,
185  std::ios_base::openmode const mode) {
186  s.open (name, mode);
187  }
188  static void close (stream_type & s) { s.close (); }
189  static void clear (stream_type &) {}
190  };
191 
192 
193  void create_log_stream (std::string const & ident);
194 
195 
196  namespace details {
197 
198  using logger_collection = std::vector<std::unique_ptr<logger>>;
199  extern thread_local logger_collection * log_destinations;
200 
201  } // end namespace details
202 
203 
204  inline bool logging_enabled () noexcept { return details::log_destinations != nullptr; }
205 
206  inline void log (logger::priority const p, gsl::not_null<gsl::czstring> const message) {
207  if (details::log_destinations != nullptr) {
208  for (std::unique_ptr<logger> & destination : *details::log_destinations) {
209  destination->log (p, message);
210  }
211  }
212  }
213  template <typename T>
214  inline void log (logger::priority p, gsl::czstring message, T d) {
215  if (details::log_destinations != nullptr) {
216  for (std::unique_ptr<logger> & destination : *details::log_destinations) {
217  destination->log (p, message, d);
218  }
219  }
220  }
221 
222 } // end namespace pstore
223 #endif // PSTORE_OS_LOGGING_HPP
Definition: logging.hpp:181
Definition: logging.hpp:173
action must be taken immediately
priority
Definition: logging.hpp:37
Definition: gsl.hpp:58
Definition: logging.hpp:141
Definition: logging.hpp:158
Cross platform file management functions and classes.
Definition: logging.hpp:102
normal, but significant, condition
Implements a portable file access API.
Definition: file.hpp:566
Definition: print.cpp:18
informational message
bool exists(std::string const &path)
Returns true if the file system contains an object at the location given by path. ...
Definition: file_posix.cpp:505
bool rename(std::string const &new_name)
Renames a file from one UTF-8 encoded path to another.
Definition: file_posix.cpp:355
Definition: nonpod2.cpp:40
The base class for logging streams.
Definition: logging.hpp:35
void unlink(std::string const &path, bool allow_noent=false)
Deletes the file system object at the location given by path.
Definition: file_posix.cpp:507
Definition: logging.hpp:127
Definition: logging.hpp:48