diff --git a/src/lib.rs b/src/lib.rs index a05d23d..2d6b82b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -140,7 +140,13 @@ impl AndroidLogger { static ANDROID_LOGGER: OnceLock = OnceLock::new(); -// Maximum length of a tag that does not require allocation. +/// Maximum length of a tag that does not require allocation. +/// +/// Tags configured explicitly in [Config] will not cause an extra allocation. When the tag is +/// derived from the module path, paths longer than this limit will trigger an allocation for each +/// log statement. +/// +/// The terminating nullbyte does not count towards this limit. const LOGGING_TAG_MAX_LEN: usize = 127; const LOGGING_MSG_MAX_LEN: usize = 4000; @@ -162,31 +168,22 @@ impl Log for AndroidLogger { return; } - // tag longer than LOGGING_TAG_MAX_LEN causes allocation + // Temporary storage for null-terminating record.module_path() if it's needed. + // Tags too long to fit here cause allocation. let mut tag_bytes: [MaybeUninit; LOGGING_TAG_MAX_LEN + 1] = uninit_array(); + // In case we end up allocating, keep the CString alive. + let _owned_tag; let module_path = record.module_path().unwrap_or_default(); - // If no tag was specified, use module name - let custom_tag = &config.tag; - let tag = custom_tag - .as_ref() - .map(|s| s.as_bytes()) - .unwrap_or_else(|| module_path.as_bytes()); - - // In case we end up allocating, keep the CString alive. - let _owned_tag; - let tag = if tag.len() < tag_bytes.len() { - // truncate the tag here to fit into LOGGING_TAG_MAX_LEN - fill_tag_bytes(&mut tag_bytes, tag) + let tag = if let Some(tag) = &config.tag { + tag + } else if module_path.len() < tag_bytes.len() { + fill_tag_bytes(&mut tag_bytes, module_path.as_bytes()) } else { // Tag longer than available stack buffer; allocate. - // We're using either - // - CString::as_bytes on config.tag, or - // - str::as_bytes on record.module_path() - // Neither of those include the terminating nullbyte. - _owned_tag = CString::new(tag) - .expect("config.tag or record.module_path() should never contain nullbytes"); + _owned_tag = CString::new(module_path.as_bytes()) + .expect("record.module_path() shouldn't contain nullbytes"); _owned_tag.as_ref() }; @@ -196,7 +193,7 @@ impl Log for AndroidLogger { // If a custom tag is used, add the module path to the message. // Use PlatformLogWriter to output chunks if they exceed max size. - let _ = match (custom_tag, &config.custom_format) { + let _ = match (&config.tag, &config.custom_format) { (_, Some(format)) => format(&mut writer, record), (Some(_), _) => fmt::write( &mut writer,