Photon 1.0.0
Loading...
Searching...
No Matches
android_sink.h
Go to the documentation of this file.
1// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
2// Distributed under the MIT License (http://opensource.org/licenses/MIT)
3
4#pragma once
5
6#ifdef __ANDROID__
7
10#include <spdlog/details/os.h>
13
14#include <android/log.h>
15#include <chrono>
16#include <mutex>
17#include <string>
18#include <thread>
19#include <type_traits>
20
21#if !defined(SPDLOG_ANDROID_RETRIES)
22#define SPDLOG_ANDROID_RETRIES 2
23#endif
24
25namespace spdlog
26{
27 namespace sinks
28 {
29
30 /*
31 * Android sink
32 * (logging using __android_log_write or __android_log_buf_write depending on the specified BufferID)
33 */
34 template <typename Mutex, int BufferID = log_id::LOG_ID_MAIN>
35 class android_sink final : public base_sink<Mutex>
36 {
37 public:
38 explicit android_sink(std::string tag = "spdlog", bool use_raw_msg = false)
39 : tag_(std::move(tag)), 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 memory_buf_t formatted;
48 if (use_raw_msg_)
49 {
50 details::fmt_helper::append_string_view(msg.payload, formatted);
51 }
52 else
53 {
54 base_sink<Mutex>::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(priority, tag_.c_str(), msg_output);
61 int retry_count = 0;
62 while ((ret == -11 /*EAGAIN*/) && (retry_count < SPDLOG_ANDROID_RETRIES))
63 {
64 details::os::sleep_for_millis(5);
65 ret = android_log(priority, tag_.c_str(), msg_output);
66 retry_count++;
67 }
68
69 if (ret < 0)
70 {
71 throw_spdlog_ex("logging to Android failed", ret);
72 }
73 }
74
75 void flush_() override
76 {
77 }
78
79 private:
80 // There might be liblog versions used, that do not support __android_log_buf_write. So we only compile and link against
81 // __android_log_buf_write, if user explicitly provides a non-default log buffer. Otherwise, when using the default log buffer, always
82 // log via __android_log_write.
83 template <int ID = BufferID>
84 typename std::enable_if<ID == static_cast<int>(log_id::LOG_ID_MAIN), int>::type android_log(int prio, const char* tag, const char* text)
85 {
86 return __android_log_write(prio, tag, text);
87 }
88
89 template <int ID = BufferID>
90 typename std::enable_if<ID != static_cast<int>(log_id::LOG_ID_MAIN), int>::type android_log(int prio, const char* tag, const char* text)
91 {
92 return __android_log_buf_write(ID, prio, tag, text);
93 }
94
95 static android_LogPriority convert_to_android_(spdlog::level::level_enum level)
96 {
97 switch (level)
98 {
100 return ANDROID_LOG_VERBOSE;
102 return ANDROID_LOG_DEBUG;
104 return ANDROID_LOG_INFO;
106 return ANDROID_LOG_WARN;
108 return ANDROID_LOG_ERROR;
110 return ANDROID_LOG_FATAL;
111 default:
112 return ANDROID_LOG_DEFAULT;
113 }
114 }
115
116 std::string tag_;
117 bool use_raw_msg_;
118 };
119
120 using android_sink_mt = android_sink<std::mutex>;
121 using android_sink_st = android_sink<details::null_mutex>;
122
123 template <int BufferId = log_id::LOG_ID_MAIN>
124 using android_sink_buf_mt = android_sink<std::mutex, BufferId>;
125 template <int BufferId = log_id::LOG_ID_MAIN>
126 using android_sink_buf_st = android_sink<details::null_mutex, BufferId>;
127
128 } // namespace sinks
129
130 // Create and register android syslog logger
131
132 template <typename Factory = spdlog::synchronous_factory>
133 inline std::shared_ptr<logger> android_logger_mt(const std::string& logger_name, const std::string& tag = "spdlog")
134 {
135 return Factory::template create<sinks::android_sink_mt>(logger_name, tag);
136 }
137
138 template <typename Factory = spdlog::synchronous_factory>
139 inline std::shared_ptr<logger> android_logger_st(const std::string& logger_name, const std::string& tag = "spdlog")
140 {
141 return Factory::template create<sinks::android_sink_st>(logger_name, tag);
142 }
143
144} // namespace spdlog
145
146#endif // __ANDROID__
type
Definition core.h:681
level_enum
Definition common.h:233
@ critical
Definition common.h:239
@ err
Definition common.h:238
@ warn
Definition common.h:237
@ info
Definition common.h:236
@ trace
Definition common.h:234
@ debug
Definition common.h:235
Definition async.h:26
SPDLOG_INLINE void throw_spdlog_ex(const std::string &msg, int last_errno)
Definition common-inl.h:75
fmt::basic_memory_buffer< char, 250 > memory_buf_t
Definition common.h:173
Definition uuid.h:926