Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 72 additions & 8 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,24 @@ env:
# - Cargo.toml
# - README.md
rust_minver: 1.63.0
ci_targets: "['', 'x86_64-apple-ios', 'x86_64-unknown-freebsd', 'x86_64-unknown-illumos', 'aarch64-linux-android']"

defaults:
run:
shell: bash

jobs:
matrix:
strategy:
fail-fast: false
runs-on: ubuntu-latest
outputs:
ci_targets: ${{ steps.generate.outputs.ci_targets }}
steps:
- name: Generate matrix
id: generate
run: echo "ci_targets=${{ env.ci_targets }}" >> $GITHUB_OUTPUT

format:
strategy:
fail-fast: false
Expand Down Expand Up @@ -78,17 +90,27 @@ jobs:
done

clippy:
needs: [matrix]
strategy:
fail-fast: false
matrix:
os: ['ubuntu-latest', 'windows-latest', 'macos-latest']
target: ${{ fromJSON(needs.matrix.outputs.ci_targets) }}
runs-on: ${{ matrix.os }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Disable bench dependencies
if: matrix.target != ''
run: ./.github/workflows/disable-bench-deps.sh
- name: Install dependencies
if: matrix.os == 'ubuntu-latest'
run: sudo bash ./.github/workflows/install-deps.sh
- name: Install Rust target
if: matrix.target != ''
run: |
rustup target add ${{ matrix.target }}
echo 'CARGO_BUILD_TARGET=${{ matrix.target }}' >> $GITHUB_ENV
- name: Install Rust nightly
run: |
rustup toolchain install nightly
Expand All @@ -98,6 +120,8 @@ jobs:
- name: Run clippy
run: cargo clippy --all-features --tests --examples -- -D warnings
- name: Run clippy nightly
# For some tier-2 targets, nightly does not provide a full pre-compile toolchain
if: matrix.target == ''
run: |
cargo +nightly clippy --all-features --tests --examples

Expand All @@ -106,6 +130,7 @@ jobs:
echo "::warning title=nightly clippy::Detected $WARNS warnings"
fi
- name: Run clippy nightly for benches
if: matrix.target == ''
run: |
cargo +nightly clippy --all-features --benches -- -A clippy::incompatible_msrv

Expand All @@ -115,11 +140,12 @@ jobs:
fi

check:
needs: [matrix]
strategy:
fail-fast: false
matrix:
os: ['ubuntu-latest', 'windows-latest', 'macos-latest']
target: ['', 'x86_64-apple-ios', 'x86_64-unknown-freebsd', 'x86_64-unknown-illumos', 'aarch64-linux-android']
target: ${{ fromJSON(needs.matrix.outputs.ci_targets) }}
runs-on: ${{ matrix.os }}
steps:
- name: Checkout repository
Expand All @@ -131,16 +157,13 @@ jobs:
run: sudo bash ./.github/workflows/install-deps.sh
- name: Install Rust target
if: matrix.target != ''
run: rustup target add ${{ matrix.target }}
run: |
rustup target add ${{ matrix.target }}
echo 'CARGO_BUILD_TARGET=${{ matrix.target }}' >> $GITHUB_ENV
- name: Restore cargo caches
uses: Swatinem/rust-cache@v2
- name: Run check
run: |
if [[ -z "${{ matrix.target }}" ]]; then
cargo check --all-features
else
cargo check --all-features --target ${{ matrix.target }}
fi
run: cargo check --all-features --verbose

check-doc:
strategy:
Expand Down Expand Up @@ -196,6 +219,47 @@ jobs:
- name: Check MSRV for core with Rust ${{ env.rust_minver }}
run: cargo +${{ env.rust_minver }} check --locked --all-features --verbose

native-test-android:
strategy:
fail-fast: false
runs-on: 'ubuntu-latest'
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Restore cargo caches
uses: Swatinem/rust-cache@v2
- name: Install cross
run: cargo install cross --git https://github.com/cross-rs/cross --verbose
- name: Build example
run: |
cross build --target x86_64-linux-android --example native_android --features native,android-ndk,source-location --verbose
mv ./target/x86_64-linux-android/debug/examples/native_android ./target/x86_64-linux-android/debug/examples/native_android_srcloc
cross build --target x86_64-linux-android --example native_android --features native,android-ndk --verbose
- name: Enable KVM
run: |
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm
- name: Run emulator and test
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: 29
arch: x86_64
script: |
adb root
adb push ./target/x86_64-linux-android/debug/examples/native_android /data
adb push ./target/x86_64-linux-android/debug/examples/native_android_srcloc /data

adb logcat -b all -c
adb shell /data/native_android
adb shell /data/native_android_srcloc
adb logcat -s "spdlog-rs-example" -d > ./logcat.log
cat ./logcat.log
cat ./logcat.log | grep "I spdlog-rs-example: \[demo] info message from spdlog-rs's AndroidSink"
cat ./logcat.log | grep "E spdlog-rs-example: \[demo] error message from spdlog-rs's AndroidSink { error_code=114514 }"
cat ./logcat.log | grep -E "I spdlog-rs-example: \[demo] \[native_android, .+.rs:[0-9]+] info message from spdlog-rs's AndroidSink"
cat ./logcat.log | grep -E "E spdlog-rs-example: \[demo] \[native_android, .+.rs:[0-9]+] error message from spdlog-rs's AndroidSink { error_code=114514 }"

bench:
needs: [test, check]
strategy:
Expand Down
8 changes: 8 additions & 0 deletions spdlog/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ release-level-trace = []
source-location = []
native = []
libsystemd = ["dep:libsystemd-sys"]
android-ndk = ["dep:android_log-sys"]
multi-thread = ["dep:crossbeam"]
runtime-pattern = ["dep:spdlog-internal"]
serde = ["dep:serde", "value-bag/serde"]
Expand Down Expand Up @@ -70,6 +71,9 @@ libc = "0.2"
[target.'cfg(target_os = "linux")'.dependencies]
libsystemd-sys = { version = "0.9.3", optional = true }

[target.'cfg(target_os = "android")'.dependencies]
android_log-sys = { version = "0.3.0", optional = true }

[dev-dependencies]
clap = { version = "3.2.23", features = ["derive"] }
crossbeam = "0.8.2"
Expand Down Expand Up @@ -173,3 +177,7 @@ required-features = ["log"]
[[example]]
name = "07_async"
required-features = ["multi-thread"]
[[example]]
name = "native_android"
path = "examples/native/android.rs"
required-features = ["native", "android-ndk"]
30 changes: 30 additions & 0 deletions spdlog/examples/native/android.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#[cfg(target_os = "android")]
fn main() -> Result<(), Box<dyn std::error::Error>> {
use std::sync::Arc;

use spdlog::{
prelude::*,
sink::{AndroidLogTag, AndroidSink},
};

let sink = Arc::new(
AndroidSink::builder()
.tag(AndroidLogTag::Custom("spdlog-rs-example".into()))
.build()?,
);
let logger = spdlog::default_logger().fork_with(|logger| {
logger.set_name(Some("demo")).unwrap();
logger.sinks_mut().push(sink);
Ok(())
})?;
spdlog::set_default_logger(logger);

info!("info message from spdlog-rs's AndroidSink");
error!("error message from spdlog-rs's AndroidSink", kv: { error_code = 114514 });
Ok(())
}

#[cfg(not(target_os = "android"))]
fn main() {
panic!("this example is only available on Android target");
}
75 changes: 75 additions & 0 deletions spdlog/src/formatter/android_formatter.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// TODO: Remove this file, use `PatternFormatter` instead
//
// Need to keep waiting for conditional space and brackets to be supported in
// pattern template strings (optional fields require these, e.g. `logger_name`)

use std::fmt::{self, Write};

use cfg_if::cfg_if;

use crate::{
formatter::{Formatter, FormatterContext},
Error, Record, StringBuf,
};

#[derive(Clone)]
pub(crate) struct AndroidFormatter {}

impl AndroidFormatter {
#[must_use]
pub(crate) fn new() -> Self {
Self {}
}

fn format_impl(
&self,
record: &Record,
dest: &mut StringBuf,
_ctx: &mut FormatterContext,
) -> Result<(), fmt::Error> {
cfg_if! {
if #[cfg(not(feature = "flexible-string"))] {
dest.reserve(crate::string_buf::RESERVE_SIZE);
}
}

if let Some(logger_name) = record.logger_name() {
dest.write_str("[")?;
dest.write_str(logger_name)?;
dest.write_str("] ")?;
}

if let Some(srcloc) = record.source_location() {
dest.write_str("[")?;
dest.write_str(srcloc.module_path())?;
dest.write_str(", ")?;
dest.write_str(srcloc.file())?;
dest.write_str(":")?;
write!(dest, "{}", srcloc.line())?;
dest.write_str("] ")?;
}

dest.write_str(record.payload())?;

record.key_values().write_to(dest, true)?;
Ok(())
}
}

impl Formatter for AndroidFormatter {
fn format(
&self,
record: &Record,
dest: &mut StringBuf,
ctx: &mut FormatterContext,
) -> crate::Result<()> {
self.format_impl(record, dest, ctx)
.map_err(Error::FormatRecord)
}
}

impl Default for AndroidFormatter {
fn default() -> Self {
Self::new()
}
}
10 changes: 10 additions & 0 deletions spdlog/src/formatter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@
//! [`SinkPropAccess::set_formatter`]: crate::sink::SinkPropAccess::set_formatter
//! [./examples]: https://github.com/SpriteOvO/spdlog-rs/tree/main/spdlog/examples

#[cfg(any(
all(target_os = "android", feature = "native", feature = "android-ndk"),
all(doc, not(doctest))
))]
mod android_formatter;
mod full_formatter;
#[cfg(any(
all(target_os = "linux", feature = "native", feature = "libsystemd"),
Expand All @@ -65,6 +70,11 @@ mod unreachable_formatter;

use std::ops::Range;

#[cfg(any(
all(target_os = "android", feature = "native", feature = "android-ndk"),
all(doc, not(doctest))
))]
pub(crate) use android_formatter::*;
use dyn_clone::*;
pub use full_formatter::*;
#[cfg(any(
Expand Down
Loading
Loading