Phase 4.1: Basis-Infrastruktur in den Core (Logging, JobManager)

- TerminalLogger, JobManager, JobStatusRow nach Core verschoben
  (Namespaces PolyTraderSharp.Services/.Models beibehalten).
- TerminalLogger: ungenutzte DB-Usings entfernt.
- Toten Stub services/logging.cs (internal class Logging) gelöscht.
- Build 0 Fehler.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
bergm
2026-07-01 16:53:38 +02:00
co-authored by Claude Opus 4.8
parent f1a5541b67
commit 9039af8d5e
4 changed files with 0 additions and 30 deletions
-15
View File
@@ -1,15 +0,0 @@
using System.ComponentModel;
using PolyTraderSharp.Models;
namespace PolyTraderSharp.Services
{
public class JobManager
{
public BindingList<JobStatusRow> Jobs { get; } = new BindingList<JobStatusRow>();
public void RegisterJob(JobStatusRow job)
{
Jobs.Add(job);
}
}
}
-118
View File
@@ -1,118 +0,0 @@
using System;
using MongoDB.Driver;
using PolyTraderSharp.Extensions;
using System.IO;
using System.Threading.Tasks;
using System.Threading.Channels;
namespace PolyTraderSharp.Services
{
public enum LogLevel { Debug, Info, Warning, Error, Trade, TradeReasoning }
public class LogMessageEventArgs : EventArgs
{
public string Message { get; }
public LogLevel Level { get; }
public DateTime Timestamp { get; }
public LogMessageEventArgs(string message, LogLevel level)
{
Message = message;
Level = level;
Timestamp = DateTime.Now;
}
}
public class TerminalLogger
{
public event EventHandler<LogMessageEventArgs>? OnLogMessage;
private readonly List<LogMessageEventArgs> _history = new();
private readonly object _lock = new();
private readonly string _logsDirectory;
private readonly Channel<LogMessageEventArgs> _logChannel;
public TerminalLogger()
{
_logsDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs");
if (!Directory.Exists(_logsDirectory))
{
Directory.CreateDirectory(_logsDirectory);
}
_logChannel = Channel.CreateUnbounded<LogMessageEventArgs>(new UnboundedChannelOptions
{
SingleReader = true
});
Task.Run(ProcessLogQueueAsync);
}
private async Task ProcessLogQueueAsync()
{
await foreach (var e in _logChannel.Reader.ReadAllAsync())
{
try
{
string dateStr = e.Timestamp.ToString("dd-MM-yyyy");
string fileName = $"{dateStr}-{e.Level}.log";
string fullPath = Path.Combine(_logsDirectory, fileName);
// Remove Emojis (Surrogate pairs and common symbols)
string safeMsg = System.Text.RegularExpressions.Regex.Replace(e.Message, @"\p{Cs}|[✅❌🌐📈🔴🧪ℹ️🚨🏆💰⬇️⬆️🔹🔸✨🔥📊📝🔄⏸️]", "");
safeMsg = safeMsg.Replace("\r\n", " | ").Replace("\n", " | ").Replace(" ", " ").Trim();
string logLine = $"[{e.Timestamp:HH:mm:ss}] {safeMsg}{Environment.NewLine}";
await File.AppendAllTextAsync(fullPath, logLine);
}
catch
{
// Ignored to prevent cascading lockups
}
}
}
public void Log(string message, LogLevel level = LogLevel.Info)
{
var e = new LogMessageEventArgs(message, level);
lock (_lock)
{
_history.Add(e);
// Optimize list pruning to avoid heavy O(N) operations per log
if (_history.Count > 10500)
{
// Remove older items efficiently in a batch
int itemsToRemove = _history.Count - 9000;
_history.RemoveRange(0, itemsToRemove);
}
}
try
{
OnLogMessage?.Invoke(this, e);
}
catch { }
// Standard Console output as fallback/debug
Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] [{level}] {message}");
_logChannel.Writer.TryWrite(e);
}
public void Info(string message) => Log(message, LogLevel.Info);
public void Debug(string message) => Log(message, LogLevel.Debug);
public void Warning(string message) => Log(message, LogLevel.Warning);
public void Error(string message) => Log(message, LogLevel.Error);
public void Trade(string message) => Log(message, LogLevel.Trade);
public void TradeReasoning(string message) => Log(message, LogLevel.TradeReasoning);
public List<LogMessageEventArgs> GetHistory(TimeSpan maxAge)
{
lock (_lock)
{
var cutoff = DateTime.Now - maxAge;
return _history.Where(x => x.Timestamp >= cutoff).ToList();
}
}
}
}
-28
View File
@@ -1,28 +0,0 @@
using System;
using MongoDB.Driver;
using PolyTraderSharp.Extensions;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PolyTraderSharp.services
{
/*
* Verwaltet alles was mit dem Logging und der Ausgabe im Terminal zu Tun hat.
*/
internal class Logging
{
/// <summary>
/// Die Loglevel Debug, Info und Error sollten klar sein.
/// Das Loglevel Trade soll Informationen zu von uns platzierten oder versucht zu platzierten Trades erhalten.
/// Das Loglevel TradeReasoning dient rein zu Analysezwecken. hier wollen wir auswerten können warum wir uns für oder gegen einen Trade entschieden haben.
/// </summary>
public enum LogLevel { Debug, Info, Trade,TradeReasoning, Error }
public void LogSchreiben( string message, LogLevel l = LogLevel.Info, bool TerminalOut = false) {
}
}
}