Befunde aus dem Testbetrieb auf der Linux-VM behoben (#572)
- #578: Abgebrochene Laeufe (Schrittgrenze, Zeitueberschreitung, Abbruch, Ausnahme) tragen ihre bezahlten Token - vorher 0 in RunUsage, fuer das Budget unsichtbar. - #580: WebFetch prueft die aufgeloeste Zieladresse beim Verbinden; ein erlaubter Name, der auf 127.0.0.1 aufloest, wird gesperrt. - #575: Dateien entstehen unter Unix mit 0600 (AtomicFile, Protokolle, FileRW-Anhaengen, state.db), Protokollverzeichnisse mit 0700. - #576: SIGTERM/SIGINT beenden auch mit Fenster geordnet. - #593: OpenRouter-Statusdienst wird gestartet. - #589: Auftragsnachricht nennt aktuelle Zeit, Zeitzone und Termin. - #581: Unvollstaendiges Argument-JSON erreicht das Werkzeug nicht mehr; das Modell bekommt eine verstaendliche Rueckmeldung statt Parsertext. - #591: Weboberflaeche liest die Felder, die API und Ereignisstrom liefern (Freigaben, Protokoll, Taskboard mit Termin, Werkzeug-Einstellungen, Tokennutzung); Ereignisstrom in camelCase. - #592: Chat zeigt Nachrichten nicht mehr doppelt. - #536 (teilweise): A2A-Antworten tragen Absender und Empfaenger, Parser wirft nicht mehr; Datums- und Volltextfilter in Agenten-Chats. - deploy/publish.py: Packager-Pfad net10.0, Schalter --agent-file. - Version 0.1.4. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Text;
|
||||
using ClawdDotNet.Core.Storage;
|
||||
|
||||
namespace ClawdDotNet.Core.Logging;
|
||||
|
||||
@@ -7,6 +8,10 @@ namespace ClawdDotNet.Core.Logging;
|
||||
/// Schreibt Log-Einträge asynchron in datei- und datumsgetrennte Logfiles.
|
||||
/// Struktur: {LogDirectory}/{Datum}/{Modul}.log
|
||||
/// Thread-safe durch ConcurrentQueue + dediziertem Writer-Task.
|
||||
///
|
||||
/// <para>Verzeichnisse <c>0700</c>, Dateien <c>0600</c> (#575): Im Protokoll stehen Pfade,
|
||||
/// Fehlermeldungen von Werkzeugen und Anfänge von Aufträgen. Vorher entstanden sie mit der
|
||||
/// Standardmaske, auf der Test-VM also <c>0775</c>/<c>0664</c>.</para>
|
||||
/// </summary>
|
||||
public sealed class FileLogWriter : IAsyncDisposable
|
||||
{
|
||||
@@ -20,7 +25,7 @@ public sealed class FileLogWriter : IAsyncDisposable
|
||||
public FileLogWriter(FileLoggerOptions options)
|
||||
{
|
||||
_options = options;
|
||||
Directory.CreateDirectory(_options.LogDirectory);
|
||||
AppPaths.EnsureDirectory(_options.LogDirectory);
|
||||
_writerTask = Task.Run(ProcessQueueAsync);
|
||||
}
|
||||
|
||||
@@ -73,7 +78,10 @@ public sealed class FileLogWriter : IAsyncDisposable
|
||||
_options.LogDirectory,
|
||||
entry.Timestamp.ToString(_options.DateFormat));
|
||||
|
||||
Directory.CreateDirectory(dateDir);
|
||||
// Nur beim Anlegen einschränken: EnsureDirectory setzt die Rechte, und das je
|
||||
// Zeile zu tun hiesse einen Systemaufruf je Protokolleintrag.
|
||||
if (!Directory.Exists(dateDir))
|
||||
AppPaths.EnsureDirectory(dateDir);
|
||||
|
||||
var safeModule = SanitizeModuleName(entry.Module);
|
||||
var filePath = Path.Combine(dateDir, $"{safeModule}.log");
|
||||
@@ -83,7 +91,12 @@ public sealed class FileLogWriter : IAsyncDisposable
|
||||
lock (fileLock)
|
||||
{
|
||||
var line = entry.Format(_options.TimestampFormat) + Environment.NewLine;
|
||||
File.AppendAllText(filePath, line, Encoding.UTF8);
|
||||
|
||||
// Wie vorher File.AppendAllText mit UTF-8: Die Präambel steht nur am Anfang
|
||||
// einer neuen Datei, weil der StreamWriter sie nur bei Position 0 schreibt.
|
||||
using var stream = OwnerOnlyFile.OpenAppend(filePath);
|
||||
using var writer = new StreamWriter(stream, Encoding.UTF8);
|
||||
writer.Write(line);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user