@@ -140,7 +140,13 @@ impl AndroidLogger {
140140
141141static ANDROID_LOGGER : OnceLock < AndroidLogger > = OnceLock :: new ( ) ;
142142
143- // Maximum length of a tag that does not require allocation.
143+ /// Maximum length of a tag that does not require allocation.
144+ ///
145+ /// Tags configured explicitly in [Config] will not cause an extra allocation. When the tag is
146+ /// derived from the module path, paths longer than this limit will trigger an allocation for each
147+ /// log statement.
148+ ///
149+ /// The terminating nullbyte does not count towards this limit.
144150const LOGGING_TAG_MAX_LEN : usize = 127 ;
145151const LOGGING_MSG_MAX_LEN : usize = 4000 ;
146152
@@ -162,32 +168,25 @@ impl Log for AndroidLogger {
162168 return ;
163169 }
164170
165- // tag longer than LOGGING_TAG_MAX_LEN causes allocation
171+ // Temporary storage for null-terminating record.module_path() if it's needed.
172+ // Tags too long to fit here cause allocation.
166173 let mut tag_bytes: [ MaybeUninit < u8 > ; LOGGING_TAG_MAX_LEN + 1 ] = uninit_array ( ) ;
174+ // In case we end up allocating, keep the CString alive.
175+ let _owned_tag;
167176
168177 let module_path = record. module_path ( ) . unwrap_or_default ( ) ;
169178
170- // If no tag was specified, use module name
171- let custom_tag = & config. tag ;
172- let tag = custom_tag
173- . as_ref ( )
174- . map ( |s| s. as_bytes ( ) )
175- . unwrap_or_else ( || module_path. as_bytes ( ) ) ;
176-
177- // In case we end up allocating, keep the CString alive.
178- let _owned_tag;
179- let tag = if tag. len ( ) < tag_bytes. len ( ) {
180- // truncate the tag here to fit into LOGGING_TAG_MAX_LEN
181- fill_tag_bytes ( & mut tag_bytes, tag)
179+ let tag: & CStr = if let Some ( ref tag) = config. tag {
180+ tag
182181 } else {
183- // Tag longer than available stack buffer; allocate.
184- // We're using either
185- // - CString::as_bytes on config.tag, or
186- // - str::as_bytes on record.module_path()
187- // Neither of those include the terminating nullbyte.
188- _owned_tag = CString :: new ( tag )
189- . expect ( "config.tag or record.module_path() should never contain nullbytes" ) ;
190- _owned_tag . as_ref ( )
182+ if module_path . len ( ) < tag_bytes . len ( ) {
183+ fill_tag_bytes ( & mut tag_bytes , module_path . as_bytes ( ) )
184+ } else {
185+ // Tag longer than available stack buffer; allocate.
186+ _owned_tag = CString :: new ( module_path . as_bytes ( ) )
187+ . expect ( "record.module_path() shouldn't contain nullbytes" ) ;
188+ _owned_tag . as_ref ( )
189+ }
191190 } ;
192191
193192 // message must not exceed LOGGING_MSG_MAX_LEN
@@ -196,7 +195,7 @@ impl Log for AndroidLogger {
196195
197196 // If a custom tag is used, add the module path to the message.
198197 // Use PlatformLogWriter to output chunks if they exceed max size.
199- let _ = match ( custom_tag , & config. custom_format ) {
198+ let _ = match ( & config . tag , & config. custom_format ) {
200199 ( _, Some ( format) ) => format ( & mut writer, record) ,
201200 ( Some ( _) , _) => fmt:: write (
202201 & mut writer,
0 commit comments