risingwave_jni_core/
tracing_slf4j.rs

1// Copyright 2025 RisingWave Labs
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::borrow::Cow;
16
17use jni::objects::JString;
18use jni::sys::{jboolean, jint};
19use tracing::Level;
20
21use crate::{EnvParam, execute_and_catch};
22
23const TARGET: &str = "risingwave_connector_node";
24
25#[unsafe(no_mangle)]
26pub(crate) extern "system" fn Java_com_risingwave_java_binding_Binding_tracingSlf4jEvent(
27    env: EnvParam<'_>,
28    thread_name: JString<'_>,
29    class_name: JString<'_>,
30    level: jint,
31    message: JString<'_>,
32    stack_trace: JString<'_>,
33) {
34    execute_and_catch(env, move |env| {
35        let thread_name = env.get_string(&thread_name)?;
36        let thread_name: Cow<'_, str> = (&thread_name).into();
37
38        let class_name = env.get_string(&class_name)?;
39        let class_name: Cow<'_, str> = (&class_name).into();
40
41        let message = env.get_string(&message)?;
42        let message: Cow<'_, str> = (&message).into();
43
44        let stack_trace = if stack_trace.is_null() {
45            None
46        } else {
47            Some(env.get_string(&stack_trace)?)
48        };
49        let stack_trace: Option<Cow<'_, str>> = stack_trace.as_ref().map(|c| c.into());
50        let stack_trace: Option<&str> = stack_trace.as_deref();
51
52        macro_rules! event {
53            ($lvl:expr) => {
54                tracing::event!(
55                    target: TARGET,
56                    $lvl,
57                    thread = &*thread_name,
58                    class = &*class_name,
59                    error = stack_trace,
60                    "{message}",
61                )
62            };
63        }
64
65        // See `com.risingwave.tracing.TracingSlf4jImpl`.
66        match level {
67            0 => event!(Level::ERROR),
68            1 => event!(Level::WARN),
69            2 => event!(Level::INFO),
70            3 => event!(Level::DEBUG),
71            4 => event!(Level::TRACE),
72            _ => unreachable!(),
73        }
74
75        Ok(())
76    })
77}
78
79#[unsafe(no_mangle)]
80pub(crate) extern "system" fn Java_com_risingwave_java_binding_Binding_tracingSlf4jEventEnabled(
81    env: EnvParam<'_>,
82    level: jint,
83) -> jboolean {
84    execute_and_catch(env, move |_env| {
85        // Currently we only support `StaticDirective` in `tracing-subscriber`, so
86        // filtering by fields like `thread` and `class` is not supported.
87        // TODO: should we support dynamic `Directive`?
88        macro_rules! event_enabled {
89            ($lvl:expr) => {
90                tracing::event_enabled!(
91                    target: TARGET,
92                    $lvl,
93                )
94            };
95        }
96
97        // See `com.risingwave.tracing.TracingSlf4jImpl`.
98        let enabled = match level {
99            0 => event_enabled!(Level::ERROR),
100            1 => event_enabled!(Level::WARN),
101            2 => event_enabled!(Level::INFO),
102            3 => event_enabled!(Level::DEBUG),
103            4 => event_enabled!(Level::TRACE),
104            _ => unreachable!(),
105        };
106
107        Ok(enabled)
108    })
109    .into()
110}