< Summary

Information
Class: ArturRios.Logging.Loggers.FileLogger
Assembly: ArturRios.Logging
File(s): D:\Repositories\dotnet-logging\src\Loggers\FileLogger.cs
Line coverage
97%
Covered lines: 74
Uncovered lines: 2
Coverable lines: 76
Total lines: 136
Line coverage: 97.3%
Branch coverage
84%
Covered branches: 16
Total branches: 19
Branch coverage: 84.2%
Method coverage
100%
Covered methods: 15
Fully covered methods: 10
Total methods: 15
Method coverage: 100%
Full method coverage: 66.6%

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
.cctor()100%11100%
Trace(...)100%11100%
Debug(...)100%11100%
Info(...)100%11100%
Warn(...)100%11100%
Error(...)100%11100%
Exception(...)100%11100%
Critical(...)100%11100%
Fatal(...)100%11100%
Write(...)100%11100%
CreateDirectoryIfNotExists(...)75%44100%
BuildFullPath()100%11100%
BuildFolderPath(...)88.88%9994.73%
BuildFileName(...)83.33%6690.9%

File(s)

D:\Repositories\dotnet-logging\src\Loggers\FileLogger.cs

#LineLine coverage
 1using ArturRios.Logging.Configuration;
 2using ArturRios.Logging.Factories;
 3using ArturRios.Logging.Interfaces;
 4
 5namespace ArturRios.Logging.Loggers;
 6
 407public class FileLogger(FileLoggerConfiguration configuration) : IInternalLogger
 8{
 9    private const string DefaultLogFolder = "log";
 10    private const string FileExtension = ".log";
 111    private static readonly Lock s_fileLock = new();
 12
 13    /// <inheritdoc />
 14    public void Trace(string message, string filePath, string methodName)
 315    {
 316        Write(CustomLogLevel.Trace, filePath, methodName, message);
 317    }
 18
 19    /// <inheritdoc />
 20    public void Debug(string message, string filePath, string methodName)
 321    {
 322        Write(CustomLogLevel.Debug, filePath, methodName, message);
 323    }
 24
 25    /// <inheritdoc />
 26    public void Info(string message, string filePath, string methodName)
 3327    {
 3328        Write(CustomLogLevel.Information, filePath, methodName, message);
 3329    }
 30
 31    /// <inheritdoc />
 32    public void Warn(string message, string filePath, string methodName)
 233    {
 234        Write(CustomLogLevel.Warning, filePath, methodName, message);
 235    }
 36
 37    /// <inheritdoc />
 38    public void Error(string message, string filePath, string methodName)
 339    {
 340        Write(CustomLogLevel.Error, filePath, methodName, message);
 341    }
 42
 43    /// <inheritdoc />
 44    public void Exception(string message, string filePath, string methodName)
 245    {
 246        Write(CustomLogLevel.Exception, filePath, methodName, message);
 247    }
 48
 49    /// <inheritdoc />
 50    public void Critical(string message, string filePath, string methodName)
 251    {
 252        Write(CustomLogLevel.Critical, filePath, methodName, message);
 253    }
 54
 55    /// <inheritdoc />
 56    public void Fatal(string message, string filePath, string methodName)
 257    {
 258        Write(CustomLogLevel.Fatal, filePath, methodName, message);
 259    }
 60
 61    private void Write(CustomLogLevel level, string filePath, string methodName, string message)
 5062    {
 5063        var path = BuildFullPath();
 64
 5065        CreateDirectoryIfNotExists(path);
 66
 67        lock (s_fileLock)
 5068        {
 5069            File.AppendAllText(path, LogEntryFactory.Create(level, filePath, methodName, message));
 5070        }
 5071    }
 72
 73    private static void CreateDirectoryIfNotExists(string path)
 5074    {
 5075        var directory = Path.GetDirectoryName(path);
 76
 5077        if (directory is not null && !Directory.Exists(directory))
 4678        {
 4679            Directory.CreateDirectory(directory);
 4680        }
 5081    }
 82
 83    private string BuildFullPath()
 5084    {
 5085        var timestamp = DateTime.UtcNow;
 5086        var folderPath = BuildFolderPath(timestamp);
 5087        var fileName = BuildFileName(timestamp);
 88
 5089        return Path.Combine(folderPath, $"{fileName}{FileExtension}");
 5090    }
 91
 92    private string BuildFolderPath(DateTime timestamp)
 5093    {
 5094        var basePath = configuration.FilePath ?? Path.Combine(AppContext.BaseDirectory, DefaultLogFolder);
 5095        var path = basePath;
 96
 5097        switch (configuration.FolderScheme)
 98        {
 99            case LogFolderScheme.AllInOne:
 44100                break;
 101            case LogFolderScheme.ByYear:
 1102                path = Path.Combine(path, timestamp.Year.ToString());
 1103                break;
 104            case LogFolderScheme.ByMonth:
 1105                path = Path.Combine(path, timestamp.Year.ToString(), timestamp.Month.ToString("D2"));
 1106                break;
 107            case LogFolderScheme.ByDay:
 1108                path = Path.Combine(path, timestamp.Year.ToString(), timestamp.Month.ToString("D2"), timestamp.Day.ToStr
 1109                break;
 110            case LogFolderScheme.ByHour:
 1111                path = Path.Combine(path, timestamp.Year.ToString(), timestamp.Month.ToString("D2"), timestamp.Day.ToStr
 1112                break;
 113            case LogFolderScheme.ByRequest:
 2114                var requestId = Guid.NewGuid().ToString();
 2115                path = Path.Combine(path, requestId);
 2116                break;
 117            default:
 0118                throw new ArgumentOutOfRangeException(configuration.FolderScheme.ToString());
 119        }
 120
 50121        return path;
 50122    }
 123
 124    private string BuildFileName(DateTime timestamp)
 50125    {
 50126        return configuration.FileSplitLevel switch
 50127        {
 1128            LogSplitLevel.Request => configuration.ApplicationName,
 1129            LogSplitLevel.Year => $"{configuration.ApplicationName}_{timestamp:yyyy}",
 1130            LogSplitLevel.Month => $"{configuration.ApplicationName}_{timestamp:yyyy_MM}",
 46131            LogSplitLevel.Day => $"{configuration.ApplicationName}_{timestamp:yyyy_MM_dd}",
 1132            LogSplitLevel.Hour => $"{configuration.ApplicationName}_{timestamp:yyyy_MM_dd_HH}",
 0133            _ => throw new ArgumentOutOfRangeException(configuration.FileSplitLevel.ToString())
 50134        };
 50135    }
 136}