spdlog
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
20# if !defined(SPDLOG_ANDROID_RETRIES)
21# define SPDLOG_ANDROID_RETRIES 2
22# endif
23
24namespace spdlog {
25namespace sinks {
26
27/*
28 * Android sink (logging using __android_log_write)
29 */
30template<typename Mutex>
31class android_sink final : public base_sink<Mutex>
32{
33public:
34 explicit android_sink(std::string tag = "spdlog", bool use_raw_msg = false)
35 : tag_(std::move(tag))
36 , use_raw_msg_(use_raw_msg)
37 {}
38
39protected:
40 void sink_it_(const details::log_msg &msg) override
41 {
42 const android_LogPriority priority = convert_to_android_(msg.level);
43 memory_buf_t formatted;
44 if (use_raw_msg_)
45 {
46 details::fmt_helper::append_string_view(msg.payload, formatted);
47 }
48 else
49 {
50 base_sink<Mutex>::formatter_->format(msg, formatted);
51 }
52 formatted.push_back('\0');
53 const char *msg_output = formatted.data();
54
55 // See system/core/liblog/logger_write.c for explanation of return value
56 int ret = __android_log_write(priority, tag_.c_str(), msg_output);
57 int retry_count = 0;
58 while ((ret == -11 /*EAGAIN*/) && (retry_count < SPDLOG_ANDROID_RETRIES))
59 {
60 details::os::sleep_for_millis(5);
61 ret = __android_log_write(priority, tag_.c_str(), msg_output);
62 retry_count++;
63 }
64
65 if (ret < 0)
66 {
67 throw_spdlog_ex("__android_log_write() failed", ret);
68 }
69 }
70
71 void flush_() override {}
72
73private:
74 static android_LogPriority convert_to_android_(spdlog::level::level_enum level)
75 {
76 switch (level)
77 {
79 return ANDROID_LOG_VERBOSE;
81 return ANDROID_LOG_DEBUG;
83 return ANDROID_LOG_INFO;
85 return ANDROID_LOG_WARN;
87 return ANDROID_LOG_ERROR;
89 return ANDROID_LOG_FATAL;
90 default:
91 return ANDROID_LOG_DEFAULT;
92 }
93 }
94
95 std::string tag_;
96 bool use_raw_msg_;
97};
98
99using android_sink_mt = android_sink<std::mutex>;
100using android_sink_st = android_sink<details::null_mutex>;
101} // namespace sinks
102
103// Create and register android syslog logger
104
105template<typename Factory = spdlog::synchronous_factory>
106inline std::shared_ptr<logger> android_logger_mt(const std::string &logger_name, const std::string &tag = "spdlog")
107{
108 return Factory::template create<sinks::android_sink_mt>(logger_name, tag);
109}
110
111template<typename Factory = spdlog::synchronous_factory>
112inline std::shared_ptr<logger> android_logger_st(const std::string &logger_name, const std::string &tag = "spdlog")
113{
114 return Factory::template create<sinks::android_sink_st>(logger_name, tag);
115}
116
117} // namespace spdlog
118
119#endif // __ANDROID__
Definition async.h:25
SPDLOG_INLINE void throw_spdlog_ex(const std::string &msg, int last_errno)
Definition common-inl.h:68
fmt::basic_memory_buffer< char, 250 > memory_buf_t
Definition common.h:116