android_sink.h
Go to the documentation of this file.
1 //
2 // Copyright(c) 2015 Gabi Melman.
3 // Distributed under the MIT License (http://opensource.org/licenses/MIT)
4 //
5 
6 #pragma once
7 
8 #ifndef SPDLOG_H
9 #include "spdlog/spdlog.h"
10 #endif
11 
14 #include "spdlog/details/os.h"
15 #include "spdlog/sinks/base_sink.h"
16 
17 #include <android/log.h>
18 #include <chrono>
19 #include <mutex>
20 #include <string>
21 #include <thread>
22 
23 #if !defined(SPDLOG_ANDROID_RETRIES)
24 #define SPDLOG_ANDROID_RETRIES 2
25 #endif
26 
27 namespace spdlog {
28 namespace sinks {
29 
30 /*
31  * Android sink (logging using __android_log_write)
32  */
33 template<typename Mutex>
34 class android_sink final : public base_sink<Mutex>
35 {
36 public:
37  explicit android_sink(std::string tag = "spdlog", bool use_raw_msg = false)
38  : tag_(std::move(tag))
39  , use_raw_msg_(use_raw_msg)
40  {
41  }
42 
43 protected:
44  void sink_it_(const details::log_msg &msg) override
45  {
46  const android_LogPriority priority = convert_to_android_(msg.level);
47  fmt::memory_buffer formatted;
48  if (use_raw_msg_)
49  {
51  }
52  else
53  {
54  sink::formatter_->format(msg, formatted);
55  }
56  formatted.push_back('\0');
57  const char *msg_output = formatted.data();
58 
59  // See system/core/liblog/logger_write.c for explanation of return value
60  int ret = __android_log_write(priority, tag_.c_str(), msg_output);
61  int retry_count = 0;
62  while ((ret == -11 /*EAGAIN*/) && (retry_count < SPDLOG_ANDROID_RETRIES))
63  {
65  ret = __android_log_write(priority, tag_.c_str(), msg_output);
66  retry_count++;
67  }
68 
69  if (ret < 0)
70  {
71  throw spdlog_ex("__android_log_write() failed", ret);
72  }
73  }
74 
75  void flush_() override {}
76 
77 private:
79  {
80  switch (level)
81  {
83  return ANDROID_LOG_VERBOSE;
85  return ANDROID_LOG_DEBUG;
87  return ANDROID_LOG_INFO;
89  return ANDROID_LOG_WARN;
90  case spdlog::level::err:
91  return ANDROID_LOG_ERROR;
93  return ANDROID_LOG_FATAL;
94  default:
95  return ANDROID_LOG_DEFAULT;
96  }
97  }
98 
101 };
102 
105 } // namespace sinks
106 
107 // Create and register android syslog logger
108 
109 template<typename Factory = default_factory>
110 inline std::shared_ptr<logger> android_logger_mt(const std::string &logger_name, const std::string &tag = "spdlog")
111 {
112  return Factory::template create<sinks::android_sink_mt>(logger_name, tag);
113 }
114 
115 template<typename Factory = default_factory>
116 inline std::shared_ptr<logger> android_logger_st(const std::string &logger_name, const std::string &tag = "spdlog")
117 {
118  return Factory::template create<sinks::android_sink_st>(logger_name, tag);
119 }
120 
121 } // namespace spdlog
std::shared_ptr< logger > android_logger_st(const std::string &logger_name, const std::string &tag="spdlog")
Definition: android_sink.h:116
basic_memory_buffer< char > memory_buffer
Definition: format.h:553
void msg(const char *fmt,...)
Definition: message.cpp:107
void sink_it_(const details::log_msg &msg) override
Definition: android_sink.h:44
std::string string
Definition: nybbler.cc:12
std::unique_ptr< spdlog::formatter > formatter_
Definition: sink.h:55
std::shared_ptr< logger > android_logger_mt(const std::string &logger_name, const std::string &tag="spdlog")
Definition: android_sink.h:110
STL namespace.
#define SPDLOG_ANDROID_RETRIES
Definition: android_sink.h:24
Definition: async.h:27
android_sink(std::string tag="spdlog", bool use_raw_msg=false)
Definition: android_sink.h:37
level::level_enum level
Definition: log_msg.h:42
def move(depos, offset)
Definition: depos.py:107
void append_string_view(spdlog::string_view_t view, fmt::basic_memory_buffer< char, Buffer_Size > &dest)
Definition: fmt_helper.h:30
level::level_enum level() const
Definition: sink.h:45
static android_LogPriority convert_to_android_(spdlog::level::level_enum level)
Definition: android_sink.h:78
const string_view_t payload
Definition: log_msg.h:52
void sleep_for_millis(int milliseconds) SPDLOG_NOEXCEPT
Definition: os.h:351