Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3494365d authored by David Duarte's avatar David Duarte Committed by Abhishek Pandit-Subedi
Browse files

gd/os/log.h: Use liblog to control logging level

liblog provides a __android_log_is_loggable function
using the standard "log.tag.<tagname>" property
to check if a given tag and priority should be printed.

This also aligns the behavior with the new
libbluetooth_log library.

Bug: 290841136
Bug: 305066880
Test: mmm packages/modules/Bluetooth
Flag: Exempt, logging change
Change-Id: I492f44c4c199d19923c3b8a4b235e784ad325ed4
parent 3aff6467
Loading
Loading
Loading
Loading
+0 −8
Original line number Diff line number Diff line
@@ -34,14 +34,6 @@ class InitFlags final {
    init_flags::load(std::move(rusted_flags));
  }

  inline static int GetLogLevelForTag(const std::string& tag) {
    return init_flags::get_log_level_for_tag(tag);
  }

  inline static int GetDefaultLogLevel() {
    return init_flags::get_default_log_level();
  }

  inline static bool IsDeviceIotConfigLoggingEnabled() {
    return init_flags::device_iot_config_logging_is_enabled();
  }
+0 −45
Original line number Diff line number Diff line
@@ -36,51 +36,6 @@ TEST(InitFlagsTest, test_leaudio_targeted_announcement_reconnection_mode) {
  ASSERT_TRUE(InitFlags::IsTargetedAnnouncementReconnectionMode());
}

TEST(InitFlagsTest, test_enable_debug_logging_for_all) {
  const char* input[] = {"INIT_default_log_level=5", nullptr};
  InitFlags::Load(input);
  ASSERT_EQ(InitFlags::GetLogLevelForTag("foo"), LOG_TAG_DEBUG);
  ASSERT_EQ(InitFlags::GetLogLevelForTag("bar"), LOG_TAG_DEBUG);
  ASSERT_EQ(InitFlags::GetDefaultLogLevel(), LOG_TAG_DEBUG);
}

TEST(InitFlagsTest, test_enable_debug_logging_for_tags) {
  const char* input[] = {"INIT_logging_debug_enabled_for_tags=foo,bar,hello", nullptr};
  InitFlags::Load(input);
  ASSERT_EQ(InitFlags::GetLogLevelForTag("foo"), LOG_TAG_VERBOSE);
  ASSERT_EQ(InitFlags::GetLogLevelForTag("bar"), LOG_TAG_VERBOSE);
  ASSERT_EQ(InitFlags::GetLogLevelForTag("hello"), LOG_TAG_VERBOSE);
  ASSERT_EQ(InitFlags::GetLogLevelForTag("Foo"), LOG_TAG_INFO);
  ASSERT_EQ(InitFlags::GetDefaultLogLevel(), LOG_TAG_INFO);
}

TEST(InitFlagsTest, test_disable_debug_logging_for_tags) {
  const char* input[] = {
      "INIT_logging_debug_disabled_for_tags=foo,bar,hello",
      "INIT_default_log_level_str=LOG_DEBUG",
      nullptr};
  InitFlags::Load(input);
  ASSERT_EQ(InitFlags::GetLogLevelForTag("foo"), LOG_TAG_INFO);
  ASSERT_EQ(InitFlags::GetLogLevelForTag("bar"), LOG_TAG_INFO);
  ASSERT_EQ(InitFlags::GetLogLevelForTag("hello"), LOG_TAG_INFO);
  ASSERT_EQ(InitFlags::GetLogLevelForTag("Foo"), LOG_TAG_DEBUG);
  ASSERT_EQ(InitFlags::GetDefaultLogLevel(), LOG_TAG_DEBUG);
}

TEST(InitFlagsTest, test_debug_logging_multiple_flags) {
  const char* input[] = {
      "INIT_logging_debug_enabled_for_tags=foo,hello",
      "INIT_logging_debug_disabled_for_tags=foo,bar",
      "INIT_default_log_level_str=LOG_WARN",
      nullptr};
  InitFlags::Load(input);
  ASSERT_EQ(InitFlags::GetLogLevelForTag("foo"), LOG_TAG_INFO);
  ASSERT_EQ(InitFlags::GetLogLevelForTag("bar"), LOG_TAG_INFO);
  ASSERT_EQ(InitFlags::GetLogLevelForTag("hello"), LOG_TAG_VERBOSE);
  ASSERT_EQ(InitFlags::GetLogLevelForTag("Foo"), LOG_TAG_WARN);
  ASSERT_EQ(InitFlags::GetDefaultLogLevel(), LOG_TAG_WARN);
}

TEST(InitFlagsTest, test_device_iot_config_logging_is_enabled) {
  const char* input[] = {"INIT_device_iot_config_logging=true", nullptr};
  InitFlags::Load(input);
+14 −28
Original line number Diff line number Diff line
@@ -57,24 +57,21 @@ static_assert(LOG_TAG != nullptr, "LOG_TAG should never be NULL");
#include <log/log.h>
#include <log/log_event_list.h>

#if __has_include("src/init_flags.rs.h")

#include "common/init_flags.h"

#define LOG_VERBOSE_INT(fmt, args...)                                                     \
  do {                                                                                    \
    if (bluetooth::common::InitFlags::GetLogLevelForTag(LOG_TAG) >= LOG_TAG_VERBOSE) { \
    if (!__android_log_is_loggable(ANDROID_LOG_VERBOSE, LOG_TAG, ANDROID_LOG_INFO) &&     \
        !__android_log_is_loggable(ANDROID_LOG_VERBOSE, "bluetooth", ANDROID_LOG_INFO)) { \
      ALOGV(fmt, ##args);                                                                 \
    }                                                                                     \
  } while (false)

#define LOG_DEBUG_INT(fmt, args...)                                                     \
  do {                                                                                  \
    if (bluetooth::common::InitFlags::GetLogLevelForTag(LOG_TAG) >= LOG_TAG_DEBUG) { \
    if (!__android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG, ANDROID_LOG_INFO) &&     \
        !__android_log_is_loggable(ANDROID_LOG_DEBUG, "bluetooth", ANDROID_LOG_INFO)) { \
      ALOGD(fmt, ##args);                                                               \
    }                                                                                   \
  } while (false)
#endif /* __has_include("src/init_flags.rs.h") */

#define LOG_INFO_INT(fmt, args...) ALOGI(fmt, ##args)
#define LOG_WARN_INT(fmt, args...) ALOGW(fmt, ##args)
@@ -102,25 +99,14 @@ static_assert(LOG_TAG != nullptr, "LOG_TAG should never be NULL");
    abort();                                                                        \
  } while (false)
#elif defined(TARGET_FLOSS) /* end of defined (ANDROID_EMULATOR) */
#include "common/init_flags.h"
#include "os/syslog.h"

// Prefix the log with tag, file, line and function
#define LOGWRAPPER(tag, fmt, args...) \
  write_syslog(tag, "%s: " fmt, LOG_TAG, ##args)

#define LOG_VERBOSE_INT(...)                                                           \
  do {                                                                                 \
    if (bluetooth::common::InitFlags::GetLogLevelForTag(LOG_TAG) >= LOG_TAG_VERBOSE) { \
      LOGWRAPPER(LOG_TAG_VERBOSE, __VA_ARGS__);                                        \
    }                                                                                  \
  } while (false)
#define LOG_DEBUG_INT(...)                                                           \
  do {                                                                               \
    if (bluetooth::common::InitFlags::GetLogLevelForTag(LOG_TAG) >= LOG_TAG_DEBUG) { \
      LOGWRAPPER(LOG_TAG_DEBUG, __VA_ARGS__);                                        \
    }                                                                                \
  } while (false)
#define LOG_VERBOSE_INT(...) LOGWRAPPER(LOG_TAG_VERBOSE, __VA_ARGS__)
#define LOG_DEBUG_INT(...) LOGWRAPPER(LOG_TAG_DEBUG, __VA_ARGS__)
#define LOG_INFO_INT(...) LOGWRAPPER(LOG_TAG_INFO, __VA_ARGS__)
#define LOG_WARN_INT(...) LOGWRAPPER(LOG_TAG_WARN, __VA_ARGS__)
#define LOG_ERROR_INT(...) LOGWRAPPER(LOG_TAG_ERROR, __VA_ARGS__)
+4 −219
Original line number Diff line number Diff line
@@ -2,7 +2,6 @@ use lazy_static::lazy_static;
use log::{error, info};
use paste::paste;
use std::collections::{BTreeMap, HashMap};
use std::convert::TryFrom;
use std::fmt;
use std::sync::Mutex;

@@ -70,25 +69,6 @@ macro_rules! create_getter_fn {
    };
}

macro_rules! create_setter_fn {
    ($flag:ident) => {
        paste! {
            #[doc = concat!(" Update value of ", stringify!($flag), " at runtime")]
            pub fn [<update_ $flag>](value: bool) {
                FLAGS.lock().unwrap().$flag = value;
            }
        }
    };
    ($flag:ident $type:ty) => {
        paste! {
            #[doc = concat!(" Update value of ", stringify!($flag), " at runtime")]
            pub fn [<update_ $flag>](value: $type) {
                FLAGS.lock().unwrap().$flag = value;
            }
        }
    };
}

macro_rules! init_flags {
    (
        name: $name:ident
@@ -116,23 +96,17 @@ macro_rules! init_flags_struct {
    (
     name: $name:ident
     flags: { $($flag:ident $(: $type:ty)? $(= $default:tt)?,)* }
     dynamic_flags: { $($dy_flag:ident $(: $dy_type:ty)? $(= $dy_default:tt)?,)* }
     extra_fields: { $($extra_field:ident : $extra_field_type:ty $(= $extra_default:tt)?,)* }
     extra_parsed_flags: { $($extra_flag:tt => $extra_flag_fn:ident(_, _ $(,$extra_args:tt)*),)*}
     dependencies: { $($parent:ident => $child:ident),* }) => {

        struct $name {
            $($flag : type_expand!($($type)?),)*
            $($dy_flag : type_expand!($($dy_type)?),)*
            $($extra_field : $extra_field_type,)*
        }

        impl Default for $name {
            fn default() -> Self {
                Self {
                    $($flag : default_value!($($type)? $(= $default)?),)*
                    $($dy_flag : default_value!($($dy_type)? $(= $dy_default)?),)*
                    $($extra_field : default_value!($extra_field_type $(= $extra_default)?),)*
                }
            }
        }
@@ -141,16 +115,12 @@ macro_rules! init_flags_struct {
            fn get_defaults_for_test() -> Self {
                Self {
                    $($flag: test_value!($($type)?),)*
                    $($dy_flag: test_value!($($dy_type)?),)*
                    $($extra_field: test_value!($extra_field_type),)*
                }
            }

            fn dump(&self) -> BTreeMap<&'static str, String> {
                [
                    $((stringify!($flag), format!("{}", self.$flag)),)*
                    $((stringify!($dy_flag), format!("{}", self.$dy_flag)),)*
                    $((stringify!($extra_field), format!("{}", self.$extra_field)),)*
                ].into()
            }

@@ -169,10 +139,6 @@ macro_rules! init_flags_struct {
                            init_flags.$flag = values[1].parse().unwrap_or_else(|e| {
                                error!("Parse failure on '{}': {}", flag, e);
                                default_value!($($type)? $(= $default)?)}),)*
                        $(concat!("INIT_", stringify!($dy_flag)) =>
                            init_flags.$dy_flag = values[1].parse().unwrap_or_else(|e| {
                                error!("Parse failure on '{}': {}", flag, e);
                                default_value!($($dy_type)? $(= $dy_default)?)}),)*
                        $($extra_flag => $extra_flag_fn(&mut init_flags, values $(, $extra_args)*),)*
                        _ => error!("Unsaved flag: {} = {}", values[0], values[1])
                    }
@@ -197,13 +163,9 @@ macro_rules! init_flags_struct {

        impl fmt::Display for $name {
            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                write!(f, concat!(
                write!(f,
                    concat!($(concat!(stringify!($flag), "={}")),*),
                    concat!($(concat!(stringify!($dy_flag), "={}")),*),
                    $(concat!(stringify!($extra_field), "={}")),*),
                    $(self.$flag),*,
                    $(self.$dy_flag),*,
                    $(self.$extra_field),*)
                    $(self.$flag),*)
            }
        }

@@ -213,16 +175,11 @@ macro_rules! init_flags_struct {
macro_rules! init_flags_getters {
    (
     flags: { $($flag:ident $(: $type:ty)? $(= $default:tt)?,)* }
     dynamic_flags: { $($dy_flag:ident $(: $dy_type:ty)? $(= $dy_default:tt)?,)* }
     extra_fields: { $($extra_field:ident : $extra_field_type:ty $(= $extra_default:tt)?,)* }
     extra_parsed_flags: { $($extra_flag:tt => $extra_flag_fn:ident(_, _ $(,$extra_args:tt)*),)*}
     dependencies: { $($parent:ident => $child:ident),* }) => {

        $(create_getter_fn!($flag $($type)?);)*

        $(create_getter_fn!($dy_flag $($dy_type)?);)*
        $(create_setter_fn!($dy_flag $($dy_type)?);)*

        #[cfg(test)]
        mod tests_autogenerated {
            use super::*;
@@ -238,19 +195,6 @@ macro_rules! init_flags_getters {
                    assert_eq!(get_value, test_value!($($type)?));
                }
            })*

            $(paste! {
                #[test]
                pub fn [<test_dynamic_get_ $dy_flag>]() {
                    let _guard = tests::ASYNC_LOCK.lock().unwrap();
                    tests::test_load(vec![
                        &*format!(concat!(concat!("INIT_", stringify!($dy_flag)), "={}"), test_value!($($dy_type)?))
                    ]);
                    let get_value = call_getter_fn!($dy_flag $($dy_type)?);
                    drop(_guard); // Prevent poisonning other tests if a panic occurs
                    assert_eq!(get_value, test_value!($($dy_type)?));
                }
            })*
        }
    }
}
@@ -266,95 +210,16 @@ impl fmt::Display for ExplicitTagSettings {
    }
}

struct LogLevel(i32);

impl TryFrom<&str> for LogLevel {
    type Error = &'static str;

    fn try_from(tag_value: &str) -> Result<Self, Self::Error> {
        match tag_value {
            "LOG_FATAL" => Ok(LogLevel(LOG_TAG_FATAL)),
            "LOG_ERROR" => Ok(LogLevel(LOG_TAG_ERROR)),
            "LOG_WARN" => Ok(LogLevel(LOG_TAG_WARN)),
            "LOG_NOTICE" => Ok(LogLevel(LOG_TAG_NOTICE)),
            "LOG_INFO" => Ok(LogLevel(LOG_TAG_INFO)),
            "LOG_DEBUG" => Ok(LogLevel(LOG_TAG_DEBUG)),
            "LOG_VERBOSE" => Ok(LogLevel(LOG_TAG_VERBOSE)),
            _ => Err("Invalid tag value"),
        }
    }
}

fn deprecated_set_debug_logging_enabled_for_all(flags: &mut InitFlags, values: Vec<&str>) {
    let truthy: bool = values[1].parse().unwrap_or(false);
    flags.default_log_level = if truthy { LOG_TAG_VERBOSE } else { LOG_TAG_INFO };

    // Leave a note that this flag is deprecated in the logs.
    log::error!(
        "DEPRECATED flag used: INIT_logging_debug_enabled_for_all. Use INIT_default_log_level_str=LOG_VERBOSE instead.",
    );
}

fn parse_log_level(flags: &mut InitFlags, values: Vec<&str>) {
    if let Ok(v) = LogLevel::try_from(values[1]) {
        flags.default_log_level = v.0;
    }
}

fn parse_logging_tag(flags: &mut InitFlags, values: Vec<&str>) {
    for tag in values[1].split(',') {
        let tagstr = tag.to_string();
        let pair = tagstr.split(':').collect::<Vec<&str>>();
        if pair.len() == 2 {
            if let Ok(v) = LogLevel::try_from(pair[1]) {
                flags.logging_explicit_tag_settings.map.insert(pair[0].into(), v.0);
            }
        }
    }
}

fn parse_debug_logging_tag(flags: &mut InitFlags, values: Vec<&str>, enabled: bool) {
    let log_level: i32 = if enabled { LOG_TAG_VERBOSE } else { LOG_TAG_INFO };

    for tag in values[1].split(',') {
        flags.logging_explicit_tag_settings.map.insert(tag.to_string(), log_level);
    }
}

fn parse_hci_adapter(flags: &mut InitFlags, values: Vec<&str>) {
    flags.hci_adapter = values[1].parse().unwrap_or(0);
}

/// Returns the log level for given flag.
pub fn get_log_level_for_tag(tag: &str) -> i32 {
    let guard = FLAGS.lock().unwrap();
    *guard.logging_explicit_tag_settings.map.get(tag).unwrap_or(&guard.default_log_level)
}

/// Sets all bool flags to true
/// Set all other flags and extra fields to their default type value
pub fn set_all_for_testing() {
    *FLAGS.lock().unwrap() = InitFlags::get_defaults_for_test();
}

// Keep these values in sync with the values in gd/os/log_tags.h
// They are used to control the log level for each tag.

/// Fatal log level.
pub const LOG_TAG_FATAL: i32 = 0;
/// Error log level.
pub const LOG_TAG_ERROR: i32 = 1;
/// Warning log level.
pub const LOG_TAG_WARN: i32 = 2;
/// Notice log level.
pub const LOG_TAG_NOTICE: i32 = 3;
/// Info log level. This is usually the default log level on most systems.
pub const LOG_TAG_INFO: i32 = 4;
/// Debug log level.
pub const LOG_TAG_DEBUG: i32 = 5;
/// Verbose log level.
pub const LOG_TAG_VERBOSE: i32 = 6;

init_flags!(
    name: InitFlags
    flags: {
@@ -395,21 +260,7 @@ init_flags!(
        att_mtu_default: i32 = 517,
        encryption_in_busy_state = true,
    }
    // dynamic flags can be updated at runtime and should be accessed directly
    // to check.
    dynamic_flags: {
        default_log_level : i32 = LOG_TAG_INFO,
    }
    // extra_fields are not a 1 to 1 match with "INIT_*" flags
    extra_fields: {
        logging_explicit_tag_settings: ExplicitTagSettings,
    }
    extra_parsed_flags: {
        "INIT_default_log_level_str" => parse_log_level(_, _),
        "INIT_log_level_for_tags" => parse_logging_tag(_, _),
        "INIT_logging_debug_enabled_for_all" => deprecated_set_debug_logging_enabled_for_all(_, _),
        "INIT_logging_debug_enabled_for_tags" => parse_debug_logging_tag(_, _, true),
        "INIT_logging_debug_disabled_for_tags" => parse_debug_logging_tag(_, _, false),
        "--hci" => parse_hci_adapter(_, _),
    }
    dependencies: {
@@ -434,9 +285,6 @@ pub fn load(raw_flags: Vec<String>) {
    let flags = InitFlags::parse(raw_flags);
    info!("Flags loaded: {}", flags);
    *FLAGS.lock().unwrap() = flags;

    // re-init to respect log levels set by flags
    crate::init_logging();
}

/// Dumps all flag K-V pairs, storing values as strings
@@ -487,29 +335,6 @@ mod tests {
        assert_eq!(get_hci_adapter(), 2);
    }
    #[test]
    fn explicit_flag() {
        let _guard = ASYNC_LOCK.lock().unwrap();
        test_load(vec![
            "INIT_default_log_level_str=LOG_VERBOSE",
            "INIT_logging_debug_enabled_for_tags=foo,bar",
            "INIT_logging_debug_disabled_for_tags=foo,bar2,fizz",
            "INIT_logging_debug_enabled_for_tags=bar2",
            "INIT_log_level_for_tags=fizz:LOG_WARN,buzz:LOG_NOTICE",
        ]);

        assert!(get_log_level_for_tag("foo") == LOG_TAG_INFO);
        assert!(get_log_level_for_tag("bar") == LOG_TAG_VERBOSE);
        assert!(get_log_level_for_tag("bar2") == LOG_TAG_VERBOSE);
        assert!(get_log_level_for_tag("unknown_flag") == LOG_TAG_VERBOSE);
        assert!(get_default_log_level() == LOG_TAG_VERBOSE);
        FLAGS.lock().unwrap().default_log_level = LOG_TAG_INFO;
        assert!(get_log_level_for_tag("foo") == LOG_TAG_INFO);
        assert!(get_log_level_for_tag("bar") == LOG_TAG_VERBOSE);
        assert!(get_log_level_for_tag("bar2") == LOG_TAG_VERBOSE);
        assert!(get_log_level_for_tag("unknown_flag") == LOG_TAG_INFO);
        assert!(get_default_log_level() == LOG_TAG_INFO);
    }
    #[test]
    fn test_redact_logging() {
        let _guard = ASYNC_LOCK.lock().unwrap();
        assert!(redact_log_is_enabled()); // default is true
@@ -520,63 +345,23 @@ mod tests {
        test_load(vec!["INIT_redact_log=true"]);
        assert!(redact_log_is_enabled()); // turned on
    }
    #[test]
    fn test_runtime_update() {
        let _guard = ASYNC_LOCK.lock().unwrap();
        test_load(vec!["INIT_private_gatt=true", "INIT_default_log_level_str=LOG_WARN"]);
        assert!(private_gatt_is_enabled());
        assert!(get_default_log_level() == LOG_TAG_WARN);

        update_default_log_level(LOG_TAG_DEBUG);
        assert!(get_default_log_level() == LOG_TAG_DEBUG);
        update_default_log_level(LOG_TAG_ERROR);
        assert!(get_default_log_level() == LOG_TAG_ERROR);
    }
    #[test]
    fn test_default_log_level() {
        // Default log level can be provided via int value or string.
        // The string version is just for ease-of-use.
        let _guard = ASYNC_LOCK.lock().unwrap();
        test_load(vec!["INIT_default_log_level=1"]);
        assert!(get_default_log_level() == LOG_TAG_ERROR);
        test_load(vec!["INIT_default_log_level_str=LOG_VERBOSE"]);
        assert!(get_default_log_level() == LOG_TAG_VERBOSE);
        test_load(vec!["INIT_default_log_level_str=LOG_VERBOSE", "INIT_default_log_level=0"]);
        assert!(get_default_log_level() == LOG_TAG_FATAL);
    }
    #[test]
    fn test_deprecated_logging_flag() {
        let _guard = ASYNC_LOCK.lock().unwrap();
        test_load(vec!["INIT_default_log_level_str=1", "INIT_logging_debug_enabled_for_all=true"]);
        assert!(get_default_log_level() == LOG_TAG_VERBOSE);
        test_load(vec!["INIT_logging_debug_enabled_for_all=false"]);
        assert!(get_default_log_level() == LOG_TAG_INFO);
    }

    init_flags_struct!(
        name: InitFlagsForTest
        flags: {
            cat,
        }
        dynamic_flags: {
            dog: i32 = 8,
        }
        extra_fields: {
            elephant: String,
        }
        extra_parsed_flags: {}
        dependencies: {}
    );

    #[test]
    fn test_dumpsys() {
        let flags = InitFlagsForTest { dog: 3, elephant: "Go bears!".into(), ..Default::default() };
        let flags = InitFlagsForTest { ..Default::default() };

        let out = flags.dump();

        assert_eq!(out.len(), 3);
        assert_eq!(out.len(), 1);
        assert_eq!(out["cat"], "false");
        assert_eq!(out["dog"], "3");
        assert_eq!(out["elephant"], "Go bears!");
    }
}
+2 −24
Original line number Diff line number Diff line
use crate::init_flags::{
    get_log_level_for_tag, LOG_TAG_DEBUG, LOG_TAG_ERROR, LOG_TAG_FATAL, LOG_TAG_INFO,
    LOG_TAG_NOTICE, LOG_TAG_VERBOSE, LOG_TAG_WARN,
};

fn get_log_level() -> log::LevelFilter {
    match get_log_level_for_tag("bluetooth_core") {
        LOG_TAG_FATAL => log::LevelFilter::Error,
        LOG_TAG_ERROR => log::LevelFilter::Error,
        LOG_TAG_WARN => log::LevelFilter::Warn,
        LOG_TAG_NOTICE => log::LevelFilter::Info,
        LOG_TAG_INFO => log::LevelFilter::Info,
        LOG_TAG_DEBUG => log::LevelFilter::Debug,
        LOG_TAG_VERBOSE => log::LevelFilter::Trace,
        _ => log::LevelFilter::Info, // default level
    }
}

/// Inits logging for Android
#[cfg(target_os = "android")]
pub fn init_logging() {
    android_logger::init_once(
        android_logger::Config::default().with_tag("bt").with_max_level(get_log_level()),
    );
    log::set_max_level(get_log_level())
    android_logger::init_once(android_logger::Config::default().with_tag("bt"));
}

/// Inits logging for host
#[cfg(not(target_os = "android"))]
pub fn init_logging() {
    env_logger::Builder::new().filter(None, get_log_level()).parse_default_env().try_init().ok();
    log::set_max_level(get_log_level())
    env_logger::Builder::new().parse_default_env().try_init().ok();
}
Loading