diff --git a/DTLib.Logging/DTLib.Logging.csproj b/DTLib.Logging/DTLib.Logging.csproj
new file mode 100644
index 0000000..4dc0bc5
--- /dev/null
+++ b/DTLib.Logging/DTLib.Logging.csproj
@@ -0,0 +1,23 @@
+
+
+
+ net6.0;net48
+ 10
+ disable
+ disable
+ true
+ embedded
+ False
+ Debug;Release
+ AnyCPU;x64;x86;arm64
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DTLib.Logging/Global.cs b/DTLib.Logging/Global.cs
new file mode 100644
index 0000000..6f7c1f3
--- /dev/null
+++ b/DTLib.Logging/Global.cs
@@ -0,0 +1,11 @@
+global using System;
+global using System.Collections;
+global using System.Collections.Generic;
+global using System.Linq;
+global using System.Text;
+global using System.Threading.Tasks;
+global using DTLib.Extensions;
+global using DTLib.Filesystem;
+
+namespace DTLib.Logging.New;
+
diff --git a/DTLib.Logging/LogFormats/DefaultLogFormat.cs b/DTLib.Logging/LogFormats/DefaultLogFormat.cs
new file mode 100644
index 0000000..144f637
--- /dev/null
+++ b/DTLib.Logging/LogFormats/DefaultLogFormat.cs
@@ -0,0 +1,28 @@
+namespace DTLib.Logging.New;
+
+public class DefaultLogFormat : ILogFormat
+{
+
+ public bool PrintTimeStamp { get; set; }
+ public bool PrintContext { get; set; }
+ public bool PrintSeverity { get; set; }
+
+ public DefaultLogFormat(bool printTimeStamp = false, bool printContext = true, bool printSeverity = true)
+ {
+ PrintTimeStamp = printTimeStamp;
+ PrintContext = printContext;
+ PrintSeverity = printSeverity;
+ }
+
+ public string CreateMessage(string context, LogSeverity severity, object message)
+ {
+ var sb = new StringBuilder();
+ if (PrintTimeStamp) sb.Append('[').Append(DateTime.Now.ToString(MyTimeFormat.ForText)).Append(']');
+ if(PrintContext) sb.Append('[').Append(context).Append(']');
+ if(PrintSeverity) sb.Append('[').Append(severity.ToString()).Append(']');
+ if (sb.Length != 0) sb.Append(": ");
+ sb.Append(message.ToString());
+ sb.Append('\n');
+ return sb.ToString();
+ }
+}
\ No newline at end of file
diff --git a/DTLib.Logging/LogFormats/ILogFormat.cs b/DTLib.Logging/LogFormats/ILogFormat.cs
new file mode 100644
index 0000000..3b1834f
--- /dev/null
+++ b/DTLib.Logging/LogFormats/ILogFormat.cs
@@ -0,0 +1,10 @@
+namespace DTLib.Logging.New;
+
+public interface ILogFormat
+{
+ bool PrintTimeStamp { get; set; }
+ bool PrintContext { get; set; }
+ bool PrintSeverity { get; set; }
+
+ string CreateMessage(string context, LogSeverity severity, object message);
+}
\ No newline at end of file
diff --git a/DTLib.Logging/LogSeverity.cs b/DTLib.Logging/LogSeverity.cs
new file mode 100644
index 0000000..dd8ddec
--- /dev/null
+++ b/DTLib.Logging/LogSeverity.cs
@@ -0,0 +1,9 @@
+namespace DTLib.Logging.New;
+
+public enum LogSeverity
+{
+ Debug=1,
+ Info=2,
+ Warn=4,
+ Error=8
+}
\ No newline at end of file
diff --git a/DTLib.Logging/Loggers/CompositeLogger.cs b/DTLib.Logging/Loggers/CompositeLogger.cs
new file mode 100644
index 0000000..d6a0c0c
--- /dev/null
+++ b/DTLib.Logging/Loggers/CompositeLogger.cs
@@ -0,0 +1,38 @@
+namespace DTLib.Logging.New;
+
+///
+/// This class can be used for unite many loggers into one
+///
+public class CompositeLogger : ILogger
+{
+ public ILogFormat Format { get; }
+ protected ILogger[] _loggers;
+
+ public CompositeLogger(ILogFormat format, params ILogger[] loggers)
+ {
+ Format = format;
+ _loggers = loggers;
+ }
+
+ public CompositeLogger(params ILogger[] loggers) : this(new DefaultLogFormat(), loggers)
+ {}
+
+
+ public void Log(string context, LogSeverity severity, object message, ILogFormat format)
+ {
+ for (int i = 0; i < _loggers.Length; i++)
+ _loggers[i].Log(context, severity, message, format);
+ }
+
+ public void Log(string context, LogSeverity severity, object message)
+ => Log(context, severity, message, Format);
+
+
+ public void Dispose()
+ {
+ for (int i = 0; i < _loggers.Length; i++)
+ {
+ _loggers[i].Dispose();
+ }
+ }
+}
\ No newline at end of file
diff --git a/DTLib.Logging/Loggers/ConsoleLogger.cs b/DTLib.Logging/Loggers/ConsoleLogger.cs
new file mode 100644
index 0000000..6f9e660
--- /dev/null
+++ b/DTLib.Logging/Loggers/ConsoleLogger.cs
@@ -0,0 +1,33 @@
+namespace DTLib.Logging.New;
+
+// вывод лога в консоль и файл
+public class ConsoleLogger : ILogger
+{
+ readonly object consolelocker = new();
+ public ILogFormat Format { get; }
+
+ public ConsoleLogger(ILogFormat format)
+ => Format = format;
+
+ public ConsoleLogger() : this(new DefaultLogFormat())
+ {}
+
+
+ public void Log(string context, LogSeverity severity, object message, ILogFormat format)
+ {
+ var msg = format.CreateMessage(context, severity, message);
+ lock (consolelocker)
+ ColoredConsole.Write(msg);
+ }
+
+ public void Log(string context, LogSeverity severity, object message)
+ => Log(context, severity, message, Format);
+
+
+ public void Dispose()
+ {
+ lock (consolelocker) {}
+ }
+
+ ~ConsoleLogger() => Dispose();
+}
diff --git a/DTLib.Logging/Loggers/FileLogger.cs b/DTLib.Logging/Loggers/FileLogger.cs
new file mode 100644
index 0000000..bfd1de7
--- /dev/null
+++ b/DTLib.Logging/Loggers/FileLogger.cs
@@ -0,0 +1,52 @@
+namespace DTLib.Logging.New;
+
+public class FileLogger : ILogger
+{
+ public ILogFormat Format { get; }
+
+ public string LogfileName { get; protected set; }
+ public System.IO.FileStream LogfileStream { get; protected set; }
+
+ public FileLogger(string logfile, ILogFormat format)
+ {
+ Format = format;
+ LogfileName = logfile;
+ LogfileStream = File.OpenAppend(logfile);
+ }
+
+ public FileLogger(string logfile) : this(logfile, new DefaultLogFormat())
+ {}
+
+ public FileLogger(string dir, string programName, ILogFormat format)
+ : this($"{dir}{Путь.Разд}{programName}_{DateTime.Now.ToString(MyTimeFormat.ForFileNames)}.log", format)
+ {}
+
+ public FileLogger(string dir, string programName) : this(dir, programName, new DefaultLogFormat())
+ {}
+
+ public void Log(string context, LogSeverity severity, object message, ILogFormat format)
+ {
+ var msg = format.CreateMessage(context, severity, format).ToBytes(StringConverter.UTF8);
+ lock (LogfileStream)
+ {
+ LogfileStream.Write(msg);
+ LogfileStream.Flush();
+ }
+ }
+
+ public void Log(string context, LogSeverity severity, object message)
+ => Log(context, severity, message, Format);
+
+ public virtual void Dispose()
+ {
+ try
+ {
+ LogfileStream?.Flush();
+ LogfileStream?.Close();
+ LogfileStream?.Dispose();
+ }
+ catch (ObjectDisposedException) { }
+ }
+
+ ~FileLogger() => Dispose();
+}
diff --git a/DTLib.Logging/Loggers/ILogger.cs b/DTLib.Logging/Loggers/ILogger.cs
new file mode 100644
index 0000000..3fbbdfb
--- /dev/null
+++ b/DTLib.Logging/Loggers/ILogger.cs
@@ -0,0 +1,9 @@
+namespace DTLib.Logging.New;
+
+public interface ILogger : IDisposable
+{
+
+ ILogFormat Format { get; }
+ void Log(string context, LogSeverity severity, object message);
+ void Log(string context, LogSeverity severity, object message, ILogFormat format);
+}
\ No newline at end of file
diff --git a/DTLib.Logging/Microsoft/LoggerService.cs b/DTLib.Logging/Microsoft/LoggerService.cs
new file mode 100644
index 0000000..e24b827
--- /dev/null
+++ b/DTLib.Logging/Microsoft/LoggerService.cs
@@ -0,0 +1,18 @@
+using Microsoft.Extensions.Logging;
+
+namespace DTLib.Logging.New.Microsoft;
+
+public class LoggerService : IServiceProvider
+{
+ ILogger _logger;
+
+ public LoggerService(ILogger logger)
+ {
+ _logger = logger;
+ }
+
+ public object GetService(Type serviceType)
+ {
+ return new MyLoggerWrapper(_logger);
+ }
+}
\ No newline at end of file
diff --git a/DTLib.Logging/Microsoft/MyLoggerWrapper.cs b/DTLib.Logging/Microsoft/MyLoggerWrapper.cs
new file mode 100644
index 0000000..1295d6d
--- /dev/null
+++ b/DTLib.Logging/Microsoft/MyLoggerWrapper.cs
@@ -0,0 +1,38 @@
+using Microsoft.Extensions.Logging;
+
+namespace DTLib.Logging.New.Microsoft;
+
+internal class MyLoggerWrapper : ILogger
+{
+ private ILogger _logger;
+ public MyLoggerWrapper(ILogger logger)=>
+ _logger = logger;
+
+ public void Log(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func formatter)
+ {
+ string message = formatter(state, exception);
+ _logger.Log(nameof(TCaller), LogSeverity_FromLogLevel(logLevel), message);
+ }
+
+ private bool _isEnabled=true;
+ public bool IsEnabled(LogLevel logLevel) => _isEnabled;
+
+ public IDisposable BeginScope(TState state)
+ {
+ throw new NotImplementedException();
+ }
+
+ static LogSeverity LogSeverity_FromLogLevel(LogLevel l)
+ => l switch
+ {
+ LogLevel.Trace => LogSeverity.Debug,
+ LogLevel.Debug => LogSeverity.Debug,
+ LogLevel.Information => LogSeverity.Info,
+ LogLevel.Warning => LogSeverity.Warn,
+ LogLevel.Error => LogSeverity.Error,
+ LogLevel.Critical => LogSeverity.Error,
+ LogLevel.None => throw new NotImplementedException("LogLevel.None is not supported"),
+ _ => throw new ArgumentOutOfRangeException(nameof(l), l, null)
+ }
+ ;
+}
\ No newline at end of file
diff --git a/DTLib.Tests/DTLib.Tests.csproj b/DTLib.Tests/DTLib.Tests.csproj
index cce9ae1..240d82e 100644
--- a/DTLib.Tests/DTLib.Tests.csproj
+++ b/DTLib.Tests/DTLib.Tests.csproj
@@ -21,6 +21,7 @@
+
diff --git a/DTLib.Tests/Program.cs b/DTLib.Tests/Program.cs
index de48fb1..a30fcb4 100644
--- a/DTLib.Tests/Program.cs
+++ b/DTLib.Tests/Program.cs
@@ -8,7 +8,7 @@ global using DTLib;
global using DTLib.Extensions;
global using DTLib.Filesystem;
global using DTLib.Dtsod;
-global using static DTLib.Logging.Tester;
+global using static DTLib.Tests.TesterLog;
global using static DTLib.Tests.Program;
using DTLib.Logging;
diff --git a/DTLib/Logging/Tester.cs b/DTLib.Tests/Tester.cs
similarity index 62%
rename from DTLib/Logging/Tester.cs
rename to DTLib.Tests/Tester.cs
index 36709e9..d868e1a 100644
--- a/DTLib/Logging/Tester.cs
+++ b/DTLib.Tests/Tester.cs
@@ -1,9 +1,9 @@
using System.Diagnostics;
-using System.Globalization;
+using DTLib.Logging;
-namespace DTLib.Logging;
+namespace DTLib.Tests;
-public static class Tester
+public static class TesterLog
{
public static void LogOperationTime(string op_name, int repeats, Action operation)
{
@@ -13,6 +13,6 @@ public static class Tester
operation();
clock.Stop();
double time=(double)(clock.ElapsedTicks)/Stopwatch.Frequency/repeats;
- Log("y",$"operation ","b",op_name,"y"," lasted ","b",time.ToString(MyTimeFormat.ForText),"y"," seconds");
+ PublicLog.Log("y",$"operation ","b",op_name,"y"," lasted ","b",time.ToString(MyTimeFormat.ForText),"y"," seconds");
}
}
\ No newline at end of file
diff --git a/DTLib.sln b/DTLib.sln
index d8569c9..b461fe0 100644
--- a/DTLib.sln
+++ b/DTLib.sln
@@ -17,6 +17,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DTLib.Dtsod", "DTLib.Dtsod\
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DTLib.Network", "DTLib.Network\DTLib.Network.csproj", "{24B7D0A2-0462-424D-B3F5-29A6655FE472}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DTLib.Logging", "DTLib.Logging\DTLib.Logging.csproj", "{00B76172-32BB-4B72-9891-47FAEF63386C}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -39,6 +41,10 @@ Global
{24B7D0A2-0462-424D-B3F5-29A6655FE472}.Debug|Any CPU.Build.0 = Debug|Any CPU
{24B7D0A2-0462-424D-B3F5-29A6655FE472}.Release|Any CPU.ActiveCfg = Release|Any CPU
{24B7D0A2-0462-424D-B3F5-29A6655FE472}.Release|Any CPU.Build.0 = Release|Any CPU
+ {00B76172-32BB-4B72-9891-47FAEF63386C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {00B76172-32BB-4B72-9891-47FAEF63386C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {00B76172-32BB-4B72-9891-47FAEF63386C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {00B76172-32BB-4B72-9891-47FAEF63386C}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE