Initial commit: IBKRTrader
.NET WinForms-Anwendung (Core, Modules/CongressTrading, UI). Enthaelt .gitignore und settings.example.json als Konfigurationsvorlage. Echte settings.json mit Zugangsdaten ist bewusst ausgeschlossen. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
namespace IBKRTrader.Core.Logging;
|
||||
|
||||
public enum AppLogLevel
|
||||
{
|
||||
Info = 0,
|
||||
Warn = 1,
|
||||
Error = 2
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace IBKRTrader.Core.Logging;
|
||||
|
||||
/// <summary>Immutable log entry – wird in Datei und RichTextBox geschrieben.</summary>
|
||||
public sealed record LogEntry(
|
||||
DateTime Timestamp,
|
||||
AppLogLevel Level,
|
||||
string Module,
|
||||
string Message,
|
||||
Exception? Exception = null
|
||||
);
|
||||
@@ -0,0 +1,105 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace IBKRTrader.Core.Logging;
|
||||
|
||||
/// <summary>
|
||||
/// Thread-sicherer Logging-Service.
|
||||
/// – Schreibt farbig in die RichTextBox (UI-Thread-safe via BeginInvoke)
|
||||
/// – Schreibt in Logs\{Module}\{Level}-dd-MM-yy.txt
|
||||
/// </summary>
|
||||
public class LoggingService
|
||||
{
|
||||
private RichTextBox? _rtb;
|
||||
private AppLogLevel _minLevel = AppLogLevel.Info;
|
||||
private readonly object _fileLock = new();
|
||||
|
||||
private static readonly string LogBaseDir =
|
||||
Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs");
|
||||
|
||||
// ─── Konfiguration ────────────────────────────────────────────────────────
|
||||
|
||||
public void AttachRichTextBox(RichTextBox rtb) => _rtb = rtb;
|
||||
|
||||
public void SetMinLevel(AppLogLevel level) => _minLevel = level;
|
||||
|
||||
// ─── Öffentliche API ─────────────────────────────────────────────────────
|
||||
|
||||
public void Info (string module, string message, Exception? ex = null)
|
||||
=> Write(AppLogLevel.Info, module, message, ex);
|
||||
|
||||
public void Warn (string module, string message, Exception? ex = null)
|
||||
=> Write(AppLogLevel.Warn, module, message, ex);
|
||||
|
||||
public void Error(string module, string message, Exception? ex = null)
|
||||
=> Write(AppLogLevel.Error, module, message, ex);
|
||||
|
||||
public void Write(AppLogLevel level, string module, string message, Exception? ex = null)
|
||||
{
|
||||
if (level < _minLevel) return;
|
||||
var entry = new LogEntry(DateTime.Now, level, module, message, ex);
|
||||
WriteToFile(entry);
|
||||
WriteToRtb(entry);
|
||||
}
|
||||
|
||||
// ─── Datei ────────────────────────────────────────────────────────────────
|
||||
|
||||
private void WriteToFile(LogEntry e)
|
||||
{
|
||||
try
|
||||
{
|
||||
var dir = Path.Combine(LogBaseDir, e.Module);
|
||||
Directory.CreateDirectory(dir);
|
||||
|
||||
var file = Path.Combine(dir, $"{e.Level}-{e.Timestamp:dd-MM-yy}.txt");
|
||||
var line = $"[{e.Timestamp:HH:mm:ss}] {e.Message}";
|
||||
if (e.Exception != null)
|
||||
line += $"\r\n {e.Exception}";
|
||||
|
||||
lock (_fileLock)
|
||||
File.AppendAllText(file, line + "\r\n");
|
||||
}
|
||||
catch { /* Logging darf niemals abstürzen */ }
|
||||
}
|
||||
|
||||
// ─── RichTextBox ──────────────────────────────────────────────────────────
|
||||
|
||||
private static readonly Color ColorInfo = Color.FromArgb(150, 210, 150);
|
||||
private static readonly Color ColorWarn = Color.FromArgb(255, 190, 60);
|
||||
private static readonly Color ColorError = Color.FromArgb(255, 80, 80);
|
||||
|
||||
private void WriteToRtb(LogEntry e)
|
||||
{
|
||||
if (_rtb == null) return;
|
||||
try
|
||||
{
|
||||
var color = e.Level switch
|
||||
{
|
||||
AppLogLevel.Warn => ColorWarn,
|
||||
AppLogLevel.Error => ColorError,
|
||||
_ => ColorInfo
|
||||
};
|
||||
var text = $"[{e.Timestamp:HH:mm:ss}] [{e.Level.ToString().ToUpper(),-5}] [{e.Module}] {e.Message}";
|
||||
if (e.Exception != null)
|
||||
text += $"\r\n {e.Exception.Message}";
|
||||
text += "\r\n";
|
||||
|
||||
if (_rtb.InvokeRequired)
|
||||
_rtb.BeginInvoke(() => AppendColored(text, color));
|
||||
else
|
||||
AppendColored(text, color);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
private void AppendColored(string text, Color color)
|
||||
{
|
||||
if (_rtb == null) return;
|
||||
_rtb.SelectionStart = _rtb.TextLength;
|
||||
_rtb.SelectionLength = 0;
|
||||
_rtb.SelectionColor = color;
|
||||
_rtb.AppendText(text);
|
||||
_rtb.SelectionColor = _rtb.ForeColor;
|
||||
if (_rtb.TextLength > 0)
|
||||
_rtb.ScrollToCaret();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user