mirror of
https://github.com/netbirdio/IronRDP.git
synced 2026-05-22 18:43:12 -07:00
feat(ffi): API for enabling tracing logs (#452)
This commit is contained in:
Generated
+2
@@ -1136,6 +1136,8 @@ dependencies = [
|
||||
"ironrdp",
|
||||
"sspi",
|
||||
"thiserror",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -22,6 +22,8 @@ diplomat-runtime = "0.7.0"
|
||||
ironrdp = { workspace = true, features = ["connector", "dvc", "svc","rdpdr","rdpsnd","graphics","input"] }
|
||||
sspi = { workspace = true, features = ["network_client"] }
|
||||
thiserror.workspace = true
|
||||
tracing.workspace = true
|
||||
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
|
||||
|
||||
[target.'cfg(windows)'.build-dependencies]
|
||||
embed-resource = "2.2.0"
|
||||
|
||||
@@ -30,6 +30,8 @@ public partial class MainWindow : Window
|
||||
|
||||
private void OnOpened(object? sender, EventArgs e)
|
||||
{
|
||||
Log.InitWithEnv();
|
||||
|
||||
WindowState = WindowState.Maximized;
|
||||
|
||||
var username = Environment.GetEnvironmentVariable("IRONRDP_USERNAME");
|
||||
|
||||
@@ -9,6 +9,8 @@ namespace Devolutions.IronRdp.ConnectExample
|
||||
{
|
||||
var arguments = ParseArguments(args);
|
||||
|
||||
Log.InitWithEnv();
|
||||
|
||||
if (arguments == null)
|
||||
{
|
||||
return;
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
// <auto-generated/> by Diplomat
|
||||
|
||||
#pragma warning disable 0105
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using Devolutions.IronRdp.Diplomat;
|
||||
#pragma warning restore 0105
|
||||
|
||||
namespace Devolutions.IronRdp;
|
||||
|
||||
#nullable enable
|
||||
|
||||
public partial class Log: IDisposable
|
||||
{
|
||||
private unsafe Raw.Log* _inner;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a managed <c>Log</c> from a raw handle.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free).
|
||||
/// <br/>
|
||||
/// This constructor assumes the raw struct is allocated on Rust side.
|
||||
/// If implemented, the custom Drop implementation on Rust side WILL run on destruction.
|
||||
/// </remarks>
|
||||
public unsafe Log(Raw.Log* handle)
|
||||
{
|
||||
_inner = handle;
|
||||
}
|
||||
|
||||
public static void InitWithEnv()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
Raw.Log.InitWithEnv();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the underlying raw handle.
|
||||
/// </summary>
|
||||
public unsafe Raw.Log* AsFFI()
|
||||
{
|
||||
return _inner;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Destroys the underlying object immediately.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Raw.Log.Destroy(_inner);
|
||||
_inner = null;
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
|
||||
~Log()
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
// <auto-generated/> by Diplomat
|
||||
|
||||
#pragma warning disable 0105
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using Devolutions.IronRdp.Diplomat;
|
||||
#pragma warning restore 0105
|
||||
|
||||
namespace Devolutions.IronRdp.Raw;
|
||||
|
||||
#nullable enable
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public partial struct Log
|
||||
{
|
||||
private const string NativeLib = "DevolutionsIronRdp";
|
||||
|
||||
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "Log_init_with_env", ExactSpelling = true)]
|
||||
public static unsafe extern void InitWithEnv();
|
||||
|
||||
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "Log_destroy", ExactSpelling = true)]
|
||||
public static unsafe extern void Destroy(Log* self);
|
||||
}
|
||||
@@ -195,7 +195,7 @@ pub mod ffi {
|
||||
performance_flags: self.performance_flags.ok_or("performance flag is missing")?,
|
||||
desktop_scale_factor: 0,
|
||||
};
|
||||
|
||||
tracing::debug!(config=?inner_config, "Built config");
|
||||
Ok(Box::new(Config(inner_config)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,6 +151,7 @@ pub mod ffi {
|
||||
let Some(connector) = self.0.as_ref() else {
|
||||
return Err(ValueConsumedError::for_item("connector").into());
|
||||
};
|
||||
tracing::trace!(pduhint=?connector.next_pdu_hint(), "Reading next PDU hint");
|
||||
Ok(connector.next_pdu_hint().map(PduHint).map(Box::new))
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ pub mod dvc;
|
||||
pub mod error;
|
||||
pub mod graphics;
|
||||
pub mod input;
|
||||
pub mod log;
|
||||
pub mod pdu;
|
||||
pub mod session;
|
||||
pub mod svc;
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
use std::{error::Error, sync::Once};
|
||||
|
||||
static INIT_LOG: Once = Once::new();
|
||||
|
||||
const IRONRDP_LOG_PATH: &str = "IRONRDP_LOG_PATH";
|
||||
const IRONRDP_LOG: &str = "IRONRDP_LOG";
|
||||
|
||||
#[diplomat::bridge]
|
||||
pub mod ffi {
|
||||
use super::{setup_logging, INIT_LOG, IRONRDP_LOG_PATH};
|
||||
|
||||
#[diplomat::opaque]
|
||||
pub struct Log;
|
||||
|
||||
impl Log {
|
||||
pub fn init_with_env() {
|
||||
INIT_LOG.call_once(|| {
|
||||
let log_file = std::env::var(IRONRDP_LOG_PATH).ok();
|
||||
let log_file = log_file.as_deref();
|
||||
setup_logging(log_file).expect("Failed to setup logging");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn setup_logging(log_file_path: Option<&str>) -> Result<(), Box<dyn Error>> {
|
||||
use std::{fs::create_dir_all, fs::OpenOptions, path::PathBuf};
|
||||
use tracing::metadata::LevelFilter;
|
||||
use tracing_subscriber::prelude::*;
|
||||
use tracing_subscriber::EnvFilter;
|
||||
|
||||
let env_filter = EnvFilter::builder()
|
||||
.with_default_directive(LevelFilter::WARN.into())
|
||||
.with_env_var(IRONRDP_LOG)
|
||||
.from_env_lossy();
|
||||
|
||||
if let Some(log_file_path) = log_file_path {
|
||||
let path = PathBuf::from(log_file_path);
|
||||
if let Some(parent) = path.parent() {
|
||||
create_dir_all(parent)?;
|
||||
}
|
||||
let file = OpenOptions::new().create(true).append(true).open(log_file_path)?;
|
||||
|
||||
let fmt_layer = tracing_subscriber::fmt::layer()
|
||||
.with_ansi(false)
|
||||
.with_writer(file)
|
||||
.compact();
|
||||
tracing_subscriber::registry()
|
||||
.with(env_filter)
|
||||
.with(fmt_layer)
|
||||
.try_init()?;
|
||||
} else {
|
||||
let fmt_layer = tracing_subscriber::fmt::layer()
|
||||
.compact()
|
||||
.with_file(true)
|
||||
.with_line_number(true)
|
||||
.with_thread_ids(true)
|
||||
.with_target(false);
|
||||
tracing_subscriber::registry()
|
||||
.with(env_filter)
|
||||
.with(fmt_layer)
|
||||
.try_init()?;
|
||||
};
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user