source: branches/properties/GDE/SINA/builddir/include/spdlog/sinks/android_sink.h

Last change on this file was 19170, checked in by westram, 3 years ago
  • sina source
    • unpack + remove tarball
    • no longer ignore sina builddir.
File size: 3.2 KB
Line 
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
12#include "spdlog/details/fmt_helper.h"
13#include "spdlog/details/null_mutex.h"
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
27namespace spdlog {
28namespace sinks {
29
30/*
31 * Android sink (logging using __android_log_write)
32 */
33template<typename Mutex>
34class android_sink final : public base_sink<Mutex>
35{
36public:
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
43protected:
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        {
50            details::fmt_helper::append_string_view(msg.payload, formatted);
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        {
64            details::os::sleep_for_millis(5);
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
77private:
78    static android_LogPriority convert_to_android_(spdlog::level::level_enum level)
79    {
80        switch (level)
81        {
82        case spdlog::level::trace:
83            return ANDROID_LOG_VERBOSE;
84        case spdlog::level::debug:
85            return ANDROID_LOG_DEBUG;
86        case spdlog::level::info:
87            return ANDROID_LOG_INFO;
88        case spdlog::level::warn:
89            return ANDROID_LOG_WARN;
90        case spdlog::level::err:
91            return ANDROID_LOG_ERROR;
92        case spdlog::level::critical:
93            return ANDROID_LOG_FATAL;
94        default:
95            return ANDROID_LOG_DEFAULT;
96        }
97    }
98
99    std::string tag_;
100    bool use_raw_msg_;
101};
102
103using android_sink_mt = android_sink<std::mutex>;
104using android_sink_st = android_sink<details::null_mutex>;
105} // namespace sinks
106
107// Create and register android syslog logger
108
109template<typename Factory = default_factory>
110inline 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
115template<typename Factory = default_factory>
116inline 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
Note: See TracBrowser for help on using the repository browser.