We use cookies for keeping user sessions alive and for site usage statistics.
Please accept cookies to continue browsing the site.

 

(You can decline cookies later navigating to page 'Privacy Policy'.)

Implement custom application logger


Application event logging is a must. But most available logging modules around are quite bloated or heavy structured. Why not create your own simple file logger and gain full control over this part of your application? Have a look.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace Common
{
    public class Logger
    {
        #region fields
        private static string LogFilePath;
        private static string BakFilePath;
        private static LogLevel LogLevel;

        private const long MAX_FILE_SIZE = 11000000;
        private const long SHRINKED_FILE_SIZE = 10000000;
        #endregion

        #region constructors
        static Logger() {
            Reset();
        }
        #endregion

        #region Reset
        public static void Reset() {
            LogFilePath = AppSettings.GetLogFilePath();
            BakFilePath = LogFilePath + @"\EventLog.txt";
            LogLevel = AppSettings.GetLogLevel();
        }
        #endregion

        #region LogInfo
        public static void LogInfo(string msg) {
            if (LogLevel > LogLevel.Information) {
                return;
            }

            writeEntry("INF", msg);
        }
        #endregion

        #region LogWarning
        public static void LogWarning(string msg) {
            if (LogLevel > LogLevel.Warning) {
                return;
            }

            writeEntry("WRN", msg);
        }
        #endregion

        #region LogError
        public static void LogError(string msg) {
            writeEntry("ERR", msg);
        }

        public static void LogError(Exception ex) {
            LogError(null, ex);
        }

        public static void LogError(string msg, Exception ex) {
            if (LogLevel > LogLevel.Error) {
                return;
            }

            var sb = new StringBuilder();

            if (msg != null) {
                sb.AppendLine(msg.Trim());
            }
            if (ex != null) {
                sb.Append(string.Format("{0}: {1}", ex.GetType(), ex.Message));
                if (ex.InnerException != null) {
                    sb.Append(string.Format(" ---> {0}: {1}", ex.InnerException.GetType(), ex.InnerException.Message));
                    if (ex.InnerException.InnerException != null) {
                        sb.Append(string.Format(" ---> {0}: {1}", ex.InnerException.InnerException.GetType(), ex.InnerException.InnerException.Message));
                    }
                }

                sb.AppendLine();
                sb.AppendLine(ex.StackTrace);
            }

            writeEntry("ERR", sb.ToString());
        }
        #endregion

        #region write entry to file
        private static void writeEntry(string key, string msg) {
            try {
                // Consider shrink file.
                if (LogFilePath != null && BakFilePath != null) {
                    try {
                        var fiLogFile = new FileInfo(LogFilePath);
                        if (fiLogFile.Exists) {
                            if (fiLogFile.Length > MAX_FILE_SIZE) {
                                considerShrinkLogFile();
                            }
                        }
                    }
                    catch {
                    }
                }

                // Write entry.
                if (LogFilePath != null) {
                    using (var fs = new FileStream(LogFilePath, FileMode.Append, FileAccess.Write, FileShare.None)) {
                        using (var wri = new StreamWriter(fs, Encoding.UTF8)) {
                            wri.WriteLine(string.Format("{0} {1} {2}",
                                DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss"),
                                key,
                                msg
                            ));
                        }
                    }
                }
            }
            catch {
                // Logging should never crash an application.
            }
        }

        private static void considerShrinkLogFile() {
            File.Copy(LogFilePath, BakFilePath, true);

            var buffer = new byte[4096];
            using (var fsRead = new FileStream(BakFilePath, FileMode.OpenOrCreate, FileAccess.Read, FileShare.None)) {
                fsRead.Position = Math.Max(0, fsRead.Length - SHRINKED_FILE_SIZE);
                using (var fsWrite = new FileStream(LogFilePath, FileMode.Create, FileAccess.Write, FileShare.None)) {
                    int cntRead = fsRead.Read(buffer, 0, buffer.Length);
                    while (cntRead > 0) {
                        fsWrite.Write(buffer, 0, cntRead);
                        cntRead = fsRead.Read(buffer, 0, buffer.Length);
                    }
                }
            }
        }
        #endregion
    }

    #region helper types
    public enum LogLevel
    {
        Information = 0, // Should have 0.
        Warning = 1,
        Error = 2
    }
    #endregion
}

Back to List