Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
sschmid committed Sep 29, 2022
0 parents commit 32d4987
Show file tree
Hide file tree
Showing 25 changed files with 867 additions and 0 deletions.
8 changes: 8 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
root = true

[*]
charset=utf-8
end_of_line=lf
trim_trailing_whitespace=true
insert_final_newline=true
indent_style=space
18 changes: 18 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# OS
.DS_Store
Thumbs.db

# Solution
obj
bin
*.userprefs
*.user
TestResults

# IDEs
.vs
.vscode
.idea

# Project
build
56 changes: 56 additions & 0 deletions Sherlog.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
Microsoft Visual Studio Solution File, Format Version 12.00
#
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Sherlog", "Sherlog", "{5BAFDDD4-9388-4E43-8CBB-C648243AE78F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sherlog", "src\Sherlog\src\Sherlog.csproj", "{5E53385B-6709-4DE3-BD63-44C7C6506189}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sherlog.Tests", "src\Sherlog\tests\Sherlog.Tests.csproj", "{DC32B1D6-8292-47DC-9900-B33EA52C01C6}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Sherlog.Appenders", "Sherlog.Appenders", "{AFF34632-3CAD-4034-A277-2CEA95A70612}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sherlog.Appenders", "src\Sherlog.Appenders\src\Sherlog.Appenders.csproj", "{0A087C52-6165-4CC1-9BF3-9866D1D8AC92}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Sherlog.Formatters", "Sherlog.Formatters", "{B6A57558-6B16-4C20-B7A3-258DF1FC28E5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sherlog.Formatters", "src\Sherlog.Formatters\src\Sherlog.Formatters.csproj", "{A90D7628-BCBC-47CB-B70D-C199FD2387E1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sherlog.Formatters.Tests", "src\Sherlog.Formatters\tests\Sherlog.Formatters.Tests.csproj", "{834C76D3-F2AC-4281-98F1-CCB8EB6B3D2D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{5E53385B-6709-4DE3-BD63-44C7C6506189}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5E53385B-6709-4DE3-BD63-44C7C6506189}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5E53385B-6709-4DE3-BD63-44C7C6506189}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5E53385B-6709-4DE3-BD63-44C7C6506189}.Release|Any CPU.Build.0 = Release|Any CPU
{DC32B1D6-8292-47DC-9900-B33EA52C01C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DC32B1D6-8292-47DC-9900-B33EA52C01C6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DC32B1D6-8292-47DC-9900-B33EA52C01C6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DC32B1D6-8292-47DC-9900-B33EA52C01C6}.Release|Any CPU.Build.0 = Release|Any CPU
{0A087C52-6165-4CC1-9BF3-9866D1D8AC92}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0A087C52-6165-4CC1-9BF3-9866D1D8AC92}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0A087C52-6165-4CC1-9BF3-9866D1D8AC92}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0A087C52-6165-4CC1-9BF3-9866D1D8AC92}.Release|Any CPU.Build.0 = Release|Any CPU
{A90D7628-BCBC-47CB-B70D-C199FD2387E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A90D7628-BCBC-47CB-B70D-C199FD2387E1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A90D7628-BCBC-47CB-B70D-C199FD2387E1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A90D7628-BCBC-47CB-B70D-C199FD2387E1}.Release|Any CPU.Build.0 = Release|Any CPU
{834C76D3-F2AC-4281-98F1-CCB8EB6B3D2D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{834C76D3-F2AC-4281-98F1-CCB8EB6B3D2D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{834C76D3-F2AC-4281-98F1-CCB8EB6B3D2D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{834C76D3-F2AC-4281-98F1-CCB8EB6B3D2D}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{5E53385B-6709-4DE3-BD63-44C7C6506189} = {5BAFDDD4-9388-4E43-8CBB-C648243AE78F}
{DC32B1D6-8292-47DC-9900-B33EA52C01C6} = {5BAFDDD4-9388-4E43-8CBB-C648243AE78F}
{0A087C52-6165-4CC1-9BF3-9866D1D8AC92} = {AFF34632-3CAD-4034-A277-2CEA95A70612}
{A90D7628-BCBC-47CB-B70D-C199FD2387E1} = {B6A57558-6B16-4C20-B7A3-258DF1FC28E5}
{834C76D3-F2AC-4281-98F1-CCB8EB6B3D2D} = {B6A57558-6B16-4C20-B7A3-258DF1FC28E5}
EndGlobalSection
EndGlobal
43 changes: 43 additions & 0 deletions src/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<Project>

<PropertyGroup>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<DefaultNetTargetFramework>net6.0</DefaultNetTargetFramework>
<DefaultTargetFramework>netstandard2.1</DefaultTargetFramework>
<DefaultTestTargetFramework>net6.0</DefaultTestTargetFramework>
<Deterministic>true</Deterministic>
<LangVersion>default</LangVersion>
<SatelliteResourceLanguages>en-US</SatelliteResourceLanguages>
</PropertyGroup>

<ItemGroup Label="NuGet">
<None Include="../../../icon.png" Pack="true" PackagePath="\" />
</ItemGroup>

<PropertyGroup Label="Docker">
<DefaultItemExcludes>$(DefaultItemExcludes);$(MSBuildProjectDirectory)/obj/**/*</DefaultItemExcludes>
<DefaultItemExcludes>$(DefaultItemExcludes);$(MSBuildProjectDirectory)/bin/**/*</DefaultItemExcludes>
</PropertyGroup>

<PropertyGroup Condition="'$(DOTNET_RUNNING_IN_CONTAINER)' == 'true'">
<BaseIntermediateOutputPath>$(MSBuildProjectDirectory)/obj/container/</BaseIntermediateOutputPath>
<BaseOutputPath>$(MSBuildProjectDirectory)/bin/container/</BaseOutputPath>
</PropertyGroup>

<PropertyGroup Condition="'$(DOTNET_RUNNING_IN_CONTAINER)' == 'true'">
<UnityEditor>$(MSBuildStartupDirectory)/build/Managed/UnityEditor.dll</UnityEditor>
<UnityEngine>$(MSBuildStartupDirectory)/build/Managed/UnityEngine.dll</UnityEngine>
</PropertyGroup>

<ItemGroup Label="Tests">
<PackageReference Update="xunit.runner.visualstudio">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Update="coverlet.collector">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>

</Project>
16 changes: 16 additions & 0 deletions src/Directory.Build.targets
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<Project>

<PropertyGroup Label="NuGet">
<Authors>Simon Schmid</Authors>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageIcon>icon.png</PackageIcon>
<PackageProjectUrl>https://github.com/sschmid/DesperateDevs</PackageProjectUrl>
<Company>Desperate Devs</Company>
<Description>$(AssemblyName)</Description>
<Copyright>Simon Schmid</Copyright>
<PackageTags>DesperateDevs, Desperate, Devs</PackageTags>
<RepositoryUrl>https://github.com/sschmid/DesperateDevs</RepositoryUrl>
<RepositoryType>git</RepositoryType>
</PropertyGroup>

</Project>
80 changes: 80 additions & 0 deletions src/Sherlog.Appenders/src/AbstractTcpSocketAppender.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
using System.Collections.Generic;
using System.Net;
using TCPeasy;

namespace Sherlog.Appenders
{
public abstract class AbstractTcpSocketAppender
{
readonly List<HistoryEntry> _history = new List<HistoryEntry>();

AbstractTcpSocket _socket;

public void Connect(IPAddress ip, int port)
{
var client = new TcpClientSocket();
_socket = client;
client.OnConnected += _ => OnConnected();
client.Connect(ip, port);
}

public void Listen(int port)
{
var server = new TcpServerSocket();
_socket = server;
server.OnClientConnected += (_, _) => OnConnected();
server.Listen(port);
}

public void Disconnect() => _socket.Disconnect();

public void Send(Logger logger, LogLevel logLevel, string message)
{
if (IsSocketReady())
_socket.Send(SerializeMessage(logger, logLevel, message));
else
_history.Add(new HistoryEntry(logger, logLevel, message));
}

bool IsSocketReady()
{
if (_socket != null)
{
if (_socket is TcpServerSocket server)
return server.Count > 0;

if (_socket is TcpClientSocket client)
return client.IsConnected;
}

return false;
}

void OnConnected()
{
if (_history.Count > 0)
{
foreach (var entry in _history)
Send(entry.Logger, entry.LogLevel, entry.Message);

_history.Clear();
}
}

protected abstract byte[] SerializeMessage(Logger logger, LogLevel logLevel, string message);

class HistoryEntry
{
public readonly Logger Logger;
public readonly LogLevel LogLevel;
public readonly string Message;

public HistoryEntry(Logger logger, LogLevel logLevel, string message)
{
Logger = logger;
LogLevel = logLevel;
Message = message;
}
}
}
}
29 changes: 29 additions & 0 deletions src/Sherlog.Appenders/src/ConsoleAppender.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System.Collections.Generic;
using System;

namespace Sherlog.Appenders
{
public class ConsoleAppender
{
readonly Dictionary<LogLevel, ConsoleColor> _consoleColors;

public ConsoleAppender(Dictionary<LogLevel, ConsoleColor> consoleColors)
{
_consoleColors = consoleColors;
}

public void WriteLine(Logger logger, LogLevel logLevel, string message)
{
if (_consoleColors.TryGetValue(logLevel, out var color))
{
Console.ForegroundColor = color;
Console.WriteLine(message);
Console.ResetColor();
}
else
{
Console.WriteLine(message);
}
}
}
}
30 changes: 30 additions & 0 deletions src/Sherlog.Appenders/src/FileWriterAppender.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System.IO;

namespace Sherlog.Appenders
{
public class FileWriterAppender
{
readonly object _lock = new object();
readonly string _filePath;

public FileWriterAppender(string filePath) => _filePath = filePath;

public void WriteLine(Logger logger, LogLevel logLevel, string message)
{
lock (_lock)
{
using var writer = new StreamWriter(_filePath, true);
writer.WriteLine(message);
}
}

public void ClearFile()
{
lock (_lock)
{
using var writer = new StreamWriter(_filePath, false);
writer.Write(string.Empty);
}
}
}
}
16 changes: 16 additions & 0 deletions src/Sherlog.Appenders/src/Sherlog.Appenders.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>$(DefaultTargetFramework)</TargetFramework>
<PackageVersion>1.0.0</PackageVersion>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="../../Sherlog/src/Sherlog.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="TCPeasy" Version="1.0.0" />
</ItemGroup>

</Project>
28 changes: 28 additions & 0 deletions src/Sherlog.Appenders/src/SosMaxAppender.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System.Text;

namespace Sherlog.Appenders
{
public class SosMaxAppender : AbstractTcpSocketAppender
{
protected override byte[] SerializeMessage(Logger logger, LogLevel logLevel, string message) =>
Encoding.UTF8.GetBytes(FormatLogMessage(logLevel.ToString(), message));

string FormatLogMessage(string logLevel, string message)
{
var lines = message.Split('\n');
return lines.Length == 1
? $"!SOS<showMessage key=\"{logLevel}\">{ReplaceXmlSymbols(message)}</showMessage>\0"
: $"!SOS<showFoldMessage key=\"{logLevel}\">{MultilineMessage(lines[0], message)}</showFoldMessage>\0";
}

string MultilineMessage(string title, string message) =>
$"<title>{ReplaceXmlSymbols(title)}</title><message>{ReplaceXmlSymbols(message.Substring(message.IndexOf('\n') + 1))}</message>";

string ReplaceXmlSymbols(string str) => str
.Replace("<", "&lt;")
.Replace(">", "&gt;")
.Replace("&lt;", "<![CDATA[<]]>")
.Replace("&gt;", "<![CDATA[>]]>")
.Replace("&", "<![CDATA[&]]>");
}
}
11 changes: 11 additions & 0 deletions src/Sherlog.Appenders/src/TcpSocketAppender.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System.Text;
using TCPeasy;

namespace Sherlog.Appenders
{
public class TcpSocketAppender : AbstractTcpSocketAppender
{
protected override byte[] SerializeMessage(Logger logger, LogLevel logLevel, string message) =>
TcpMessageParser.WrapMessage(Encoding.UTF8.GetBytes(message));
}
}
51 changes: 51 additions & 0 deletions src/Sherlog.Formatters/src/ColorCodeFormatter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
using System.Collections.Generic;

namespace Sherlog.Formatters
{
public class ColorCodeFormatter
{
// ANSI COLOR escape codes for colors and other things.
// You can change the color of foreground and background plus bold, italic, underline etc
// For a complete list see http://en.wikipedia.org/wiki/ANSI_escape_code#Colors

public const string Reset = "0m";
public const string Esc = "\x1B[";

public const string NoBackground = "";
public const string BlackForeground = "30m";
public const string BlackBackground = "40m";
public const string RedForeground = "31m";
public const string RedBackground = "41m";
public const string GreenForeground = "32m";
public const string GreenBackground = "42m";
public const string YellowForeground = "33m";
public const string YellowBackground = "43m";
public const string BlueForeground = "34m";
public const string BlueBackground = "44m";
public const string MagentaForeground = "35m";
public const string MagentaBackground = "45m";
public const string CyanForeground = "36m";
public const string CyanBackground = "46m";
public const string WhiteForeground = "37m";
public const string WhiteBackground = "47m";

public class Color
{
public string Foreground;
public string Background;
}

public readonly Dictionary<LogLevel, Color> Colors = new Dictionary<LogLevel, Color>
{
{LogLevel.Trace, new Color {Foreground = WhiteForeground, Background = CyanBackground}},
{LogLevel.Debug, new Color {Foreground = BlueForeground, Background = NoBackground}},
{LogLevel.Info, new Color {Foreground = GreenForeground, Background = NoBackground}},
{LogLevel.Warn, new Color {Foreground = YellowForeground, Background = NoBackground}},
{LogLevel.Error, new Color {Foreground = WhiteForeground, Background = RedBackground}},
{LogLevel.Fatal, new Color {Foreground = WhiteForeground, Background = MagentaBackground}}
};

public string FormatMessage(Logger logger, LogLevel logLevel, string message) =>
$"{Esc}{Colors[logLevel].Background}{Esc}{Colors[logLevel].Foreground}{message}{Esc}{Reset}";
}
}
Loading

0 comments on commit 32d4987

Please sign in to comment.