65
65
66
66
#[ cfg( target_os = "android" ) ]
67
67
extern crate android_log_sys as log_ffi;
68
- # [ macro_use ]
69
- extern crate lazy_static ;
68
+ extern crate once_cell ;
69
+ use once_cell :: sync :: OnceCell ;
70
70
#[ macro_use]
71
71
extern crate log;
72
72
73
73
extern crate env_logger;
74
74
75
- use std:: sync:: RwLock ;
76
-
77
75
#[ cfg( target_os = "android" ) ]
78
76
use log_ffi:: LogPriority ;
79
77
use log:: { Level , Log , Metadata , Record } ;
@@ -105,21 +103,20 @@ fn android_log(_priority: Level, _tag: &CStr, _msg: &CStr) {}
105
103
106
104
/// Underlying android logger backend
107
105
pub struct AndroidLogger {
108
- config : RwLock < Config > ,
106
+ config : OnceCell < Config > ,
109
107
}
110
108
111
109
impl AndroidLogger {
112
110
/// Create new logger instance from config
113
111
pub fn new ( config : Config ) -> AndroidLogger {
114
112
AndroidLogger {
115
- config : RwLock :: new ( config) ,
113
+ config : OnceCell :: from ( config) ,
116
114
}
117
115
}
118
116
}
119
117
120
- lazy_static ! {
121
- static ref ANDROID_LOGGER : AndroidLogger = AndroidLogger :: default ( ) ;
122
- }
118
+
119
+ static ANDROID_LOGGER : OnceCell < AndroidLogger > = OnceCell :: new ( ) ;
123
120
124
121
const LOGGING_TAG_MAX_LEN : usize = 23 ;
125
122
const LOGGING_MSG_MAX_LEN : usize = 4000 ;
@@ -128,7 +125,7 @@ impl Default for AndroidLogger {
128
125
/// Create a new logger with default config
129
126
fn default ( ) -> AndroidLogger {
130
127
AndroidLogger {
131
- config : RwLock :: new ( Config :: default ( ) ) ,
128
+ config : OnceCell :: from ( Config :: default ( ) ) ,
132
129
}
133
130
}
134
131
}
@@ -140,8 +137,7 @@ impl Log for AndroidLogger {
140
137
141
138
fn log ( & self , record : & Record ) {
142
139
let config = self . config
143
- . read ( )
144
- . expect ( "failed to acquire android_log filter lock for read" ) ;
140
+ . get_or_init ( Config :: default) ;
145
141
146
142
if !config. filter_matches ( record) {
147
143
return ;
@@ -423,7 +419,7 @@ impl<'a> fmt::Write for PlatformLogWriter<'a> {
423
419
/// This action does not require initialization. However, without initialization it
424
420
/// will use the default filter, which allows all logs.
425
421
pub fn log ( record : & Record ) {
426
- ANDROID_LOGGER . log ( record)
422
+ ANDROID_LOGGER . get_or_init ( AndroidLogger :: default ) . log ( record)
427
423
}
428
424
429
425
/// Initializes the global logger with an android logger.
@@ -434,16 +430,13 @@ pub fn log(record: &Record) {
434
430
/// It is ok to call this at the activity creation, and it will be
435
431
/// repeatedly called on every lifecycle restart (i.e. screen rotation).
436
432
pub fn init_once ( config : Config ) {
437
- if let Err ( err) = log:: set_logger ( & * ANDROID_LOGGER ) {
433
+ let log_level = config. log_level ;
434
+ let logger = ANDROID_LOGGER . get_or_init ( || AndroidLogger :: new ( config) ) ;
435
+
436
+ if let Err ( err) = log:: set_logger ( logger) {
438
437
debug ! ( "android_logger: log::set_logger failed: {}" , err) ;
439
- } else {
440
- if let Some ( level) = config. log_level {
441
- log:: set_max_level ( level. to_level_filter ( ) ) ;
442
- }
443
- * ANDROID_LOGGER
444
- . config
445
- . write ( )
446
- . expect ( "failed to acquire android_log filter lock for write" ) = config;
438
+ } else if let Some ( level) = log_level {
439
+ log:: set_max_level ( level. to_level_filter ( ) ) ;
447
440
}
448
441
}
449
442
0 commit comments