mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2025-04-27 15:39:47 +00:00
Added paths to log files in the "About" dialog for easier support (#304)
This commit is contained in:
parent
277dc73468
commit
9d2b63bbaa
@ -26,6 +26,38 @@
|
||||
<ExpansionPanel HeaderIcon="@Icons.Material.Filled.EventNote" HeaderText="Changelog">
|
||||
<Changelog/>
|
||||
</ExpansionPanel>
|
||||
|
||||
<ExpansionPanel HeaderIcon="@Icons.Material.Filled.Book" HeaderText="Logbook">
|
||||
<MudText Typo="Typo.h4">
|
||||
Explanation
|
||||
</MudText>
|
||||
<MudJustifiedText Class="mb-3" Typo="Typo.body1">
|
||||
AI Studio creates a log file at startup, in which events during startup are recorded. After startup,
|
||||
another log file is created that records all events that occur during the use of the app. This
|
||||
includes any errors that may occur. Depending on when an error occurs (at startup or during use),
|
||||
the contents of these log files can be helpful for troubleshooting. Sensitive information such as
|
||||
passwords is not included in the log files.
|
||||
</MudJustifiedText>
|
||||
|
||||
<MudJustifiedText Class="mb-3" Typo="Typo.body1">
|
||||
By clicking on the respective path, the path is copied to the clipboard. You might open these files
|
||||
with a text editor to view their contents.
|
||||
</MudJustifiedText>
|
||||
|
||||
<MudText Typo="Typo.h4">
|
||||
Startup log file
|
||||
</MudText>
|
||||
<MudList T="string" Class="mb-3">
|
||||
<MudListItem T="string" Icon="@Icons.Material.Outlined.Folder" Text="@this.logPaths.LogStartupPath" OnClick="() => this.CopyStartupLogPath()"/>
|
||||
</MudList>
|
||||
|
||||
<MudText Typo="Typo.h4">
|
||||
Usage log file
|
||||
</MudText>
|
||||
<MudList T="string" Class="mb-3">
|
||||
<MudListItem T="string" Icon="@Icons.Material.Outlined.Folder" Text="@this.logPaths.LogAppPath" OnClick="() => this.CopyAppLogPath()"/>
|
||||
</MudList>
|
||||
</ExpansionPanel>
|
||||
|
||||
<ExpansionPanel HeaderIcon="@Icons.Material.Filled.Engineering" HeaderText="Motivation">
|
||||
<Motivation/>
|
||||
|
@ -1,5 +1,8 @@
|
||||
using System.Reflection;
|
||||
|
||||
using AIStudio.Tools.Rust;
|
||||
using AIStudio.Tools.Services;
|
||||
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
namespace AIStudio.Pages;
|
||||
@ -9,9 +12,15 @@ public partial class About : ComponentBase
|
||||
[Inject]
|
||||
private MessageBus MessageBus { get; init; } = null!;
|
||||
|
||||
[Inject]
|
||||
private RustService RustService { get; init; } = null!;
|
||||
|
||||
[Inject]
|
||||
private ISnackbar Snackbar { get; init; } = null!;
|
||||
|
||||
private static readonly Assembly ASSEMBLY = Assembly.GetExecutingAssembly();
|
||||
private static readonly MetaDataAttribute META_DATA = ASSEMBLY.GetCustomAttribute<MetaDataAttribute>()!;
|
||||
|
||||
|
||||
private static string VersionDotnetRuntime => $"Used .NET runtime: v{META_DATA.DotnetVersion}";
|
||||
|
||||
private static string VersionDotnetSdk => $"Used .NET SDK: v{META_DATA.DotnetSdkVersion}";
|
||||
@ -26,6 +35,28 @@ public partial class About : ComponentBase
|
||||
|
||||
private static string TauriVersion => $"Tauri: v{META_DATA.TauriVersion}";
|
||||
|
||||
private GetLogPathsResponse logPaths;
|
||||
|
||||
#region Overrides of ComponentBase
|
||||
|
||||
private async Task CopyStartupLogPath()
|
||||
{
|
||||
await this.RustService.CopyText2Clipboard(this.Snackbar, this.logPaths.LogStartupPath);
|
||||
}
|
||||
|
||||
private async Task CopyAppLogPath()
|
||||
{
|
||||
await this.RustService.CopyText2Clipboard(this.Snackbar, this.logPaths.LogAppPath);
|
||||
}
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
this.logPaths = await this.RustService.GetLogPaths();
|
||||
await base.OnInitializedAsync();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private const string LICENSE = """
|
||||
# Functional Source License, Version 1.1, MIT Future License
|
||||
|
||||
|
3
app/MindWork AI Studio/Tools/Rust/GetLogPathsResponse.cs
Normal file
3
app/MindWork AI Studio/Tools/Rust/GetLogPathsResponse.cs
Normal file
@ -0,0 +1,3 @@
|
||||
namespace AIStudio.Tools.Rust;
|
||||
|
||||
public readonly record struct GetLogPathsResponse(string LogStartupPath, string LogAppPath);
|
15
app/MindWork AI Studio/Tools/Services/RustService.Log.cs
Normal file
15
app/MindWork AI Studio/Tools/Services/RustService.Log.cs
Normal file
@ -0,0 +1,15 @@
|
||||
using AIStudio.Tools.Rust;
|
||||
|
||||
namespace AIStudio.Tools.Services;
|
||||
|
||||
public sealed partial class RustService
|
||||
{
|
||||
/// <summary>
|
||||
/// Get the paths of the log files.
|
||||
/// </summary>
|
||||
/// <returns>The paths of the log files.</returns>
|
||||
public async Task<GetLogPathsResponse> GetLogPaths()
|
||||
{
|
||||
return await this.http.GetFromJsonAsync<GetLogPathsResponse>("/log/paths", this.jsonRustSerializerOptions);
|
||||
}
|
||||
}
|
@ -2,3 +2,4 @@
|
||||
- Added Helmholtz (aka "Blablador") as provider. This provider is available to all researchers and employees of the 18 Helmholtz Centers as well as all eduGAIN organizations worldwide.
|
||||
- Added GWDG SAIA as provider. This provider is available to all researchers and employees of the GWDG, the Max Planck Society, the 18 Helmholtz Centers, and most German universities.
|
||||
- Added DeepSeek as provider.
|
||||
- Added paths to log files in the "About" dialog for easier troubleshooting and support.
|
@ -7,10 +7,18 @@ use flexi_logger::{DeferredNow, Duplicate, FileSpec, Logger, LoggerHandle};
|
||||
use flexi_logger::writers::FileLogWriter;
|
||||
use log::kv;
|
||||
use log::kv::{Key, Value, VisitSource};
|
||||
use rocket::get;
|
||||
use rocket::serde::json::Json;
|
||||
use rocket::serde::Serialize;
|
||||
use crate::api_token::APIToken;
|
||||
use crate::environment::is_dev;
|
||||
|
||||
static LOGGER: OnceLock<RuntimeLoggerHandle> = OnceLock::new();
|
||||
|
||||
static LOG_STARTUP_PATH: OnceLock<String> = OnceLock::new();
|
||||
|
||||
static LOG_APP_PATH: OnceLock<String> = OnceLock::new();
|
||||
|
||||
/// Initialize the logging system.
|
||||
pub fn init_logging() {
|
||||
|
||||
@ -42,11 +50,16 @@ pub fn init_logging() {
|
||||
false => "AI Studio Events",
|
||||
};
|
||||
|
||||
let log_path = FileSpec::default()
|
||||
.basename(log_basename)
|
||||
.suppress_timestamp()
|
||||
.suffix("log");
|
||||
|
||||
// Store the startup log path:
|
||||
LOG_STARTUP_PATH.set(log_path.as_pathbuf(None).canonicalize().unwrap().to_str().unwrap().to_string()).expect("Cannot store the startup log path");
|
||||
|
||||
let runtime_logger = Logger::try_with_str(log_config).expect("Cannot create logging")
|
||||
.log_to_file(FileSpec::default()
|
||||
.basename(log_basename)
|
||||
.suppress_timestamp()
|
||||
.suffix("log"))
|
||||
.log_to_file(log_path)
|
||||
.duplicate_to_stdout(Duplicate::All)
|
||||
.use_utc()
|
||||
.format_for_files(file_logger_format)
|
||||
@ -63,12 +76,13 @@ pub fn init_logging() {
|
||||
|
||||
/// Switch the logging system to a file-based output.
|
||||
pub fn switch_to_file_logging(logger_path: PathBuf) -> Result<(), Box<dyn Error>>{
|
||||
LOGGER.get().expect("No LOGGER was set").handle.reset_flw(&FileLogWriter::builder(
|
||||
FileSpec::default()
|
||||
.directory(logger_path)
|
||||
.basename("events")
|
||||
.suppress_timestamp()
|
||||
.suffix("log")))?;
|
||||
let log_path = FileSpec::default()
|
||||
.directory(logger_path)
|
||||
.basename("events")
|
||||
.suppress_timestamp()
|
||||
.suffix("log");
|
||||
LOG_APP_PATH.set(log_path.as_pathbuf(None).to_str().unwrap().to_string()).expect("Cannot store the app log path");
|
||||
LOGGER.get().expect("No LOGGER was set").handle.reset_flw(&FileLogWriter::builder(log_path))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -160,4 +174,19 @@ fn file_logger_format(
|
||||
|
||||
// Write the log message:
|
||||
write!(w, "{}", &record.args())
|
||||
}
|
||||
|
||||
#[get("/log/paths")]
|
||||
pub async fn get_log_paths(_token: APIToken) -> Json<LogPathsResponse> {
|
||||
Json(LogPathsResponse {
|
||||
log_startup_path: LOG_STARTUP_PATH.get().expect("No startup log path was set").clone(),
|
||||
log_app_path: LOG_APP_PATH.get().expect("No app log path was set").clone(),
|
||||
})
|
||||
}
|
||||
|
||||
/// The response the get log paths request.
|
||||
#[derive(Serialize)]
|
||||
pub struct LogPathsResponse {
|
||||
log_startup_path: String,
|
||||
log_app_path: String,
|
||||
}
|
@ -77,6 +77,7 @@ pub fn start_runtime_api() {
|
||||
crate::secret::delete_secret,
|
||||
crate::environment::get_data_directory,
|
||||
crate::environment::get_config_directory,
|
||||
crate::log::get_log_paths,
|
||||
])
|
||||
.ignite().await.unwrap()
|
||||
.launch().await.unwrap();
|
||||
|
Loading…
Reference in New Issue
Block a user