[Guide] How I handle log files! menu

User Tag List

Results 1 to 1 of 1
  1. #1
    Viano's Avatar Active Member
    Reputation
    37
    Join Date
    May 2008
    Posts
    172
    Thanks G/R
    0/1
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    [Guide] How I handle log files!

    Hello everyone,

    I am a beginner in C# but I would like to show you my classes for handling log files in my private bot program. The goal is to write a log file in your application's current directory and show every change to the log file as new line in a text box on your form.

    The first class uses the SystemFileWatcher class (FileSystemWatcher Class (System.IO), please read this) which raises events on selected file or directory changes. The strategy is to add new content to our text box as soon as the log file changes and event is raised.

    Code:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    using System.IO;
    using System.Windows.Forms;
    
    namespace LogWatcher
    {
        /// <summary>
        /// This class is used for log file monitoring.
        /// </summary>
        class LogFileMonitor
        {
            /// <summary>
            /// This class is enabling event based file system monitoring.
            /// </summary>
            private FileSystemWatcher _fswatcher;
    
            /// <summary>
            /// Reading files is done by a stream reader.
            /// </summary>
            private StreamReader _stream;
    
            /// <summary>
            /// The last line from the log file is appended to this text box.
            /// </summary>
            private TextBox _textBox;
    
            /// <summary>
            /// We are holding file lines in here.
            /// </summary>
            private List<string> _data;
    
            /// <summary>
            /// Delegate for text box updating method.
            /// </summary>
            private delegate void UpdateTextBoxDelegate();
    
            /// <summary>
            /// Several threads are using the log file so we have to synchronize.
            /// </summary>
            private Object _lockThis = new Object();
    
            /// <summary>
            /// Our log file name.
            /// </summary>
            private string _file = "";
    
            /// <summary>
            /// And this is for saving lines from the log file.
            /// </summary>
            private string _line = "";
    
            public LogFileMonitor(string file, TextBox textBox) 
            {
                /* instantiate objects */
                _data = new List<string>();
                _fswatcher = new FileSystemWatcher();
    
                /* set variables */
                _textBox = textBox;
                _file = file;
    
                /* configure file system watcher */           
                _fswatcher.Path = Directory.GetCurrentDirectory();
                _fswatcher.Filter = _file;
                _fswatcher.NotifyFilter = NotifyFilters.LastWrite;
                _fswatcher.Changed += new FileSystemEventHandler(LogFileChanged);            
                _fswatcher.EnableRaisingEvents = true;
            }
    
            /// <summary>
            /// This is executed when we write to the log file.
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void LogFileChanged(object sender, FileSystemEventArgs e) 
            {
                /* invoking is needed for accessing visual elements from threads */
                if (_textBox.InvokeRequired) 
                {
                    _textBox.Invoke(new UpdateTextBoxDelegate(UpdateTextBoxCallback));
                }
                else
                {
                    UpdateTextBoxCallback();
                }
            }
    
            /// <summary>
            /// This function read the whole file and updates our text box with last line from file.
            /// </summary>
            private void UpdateTextBoxCallback() 
            {
                _data.Clear();
    
                /* remember that other threads are using the file */
                lock (_lockThis)
                {
                    _stream = File.OpenText(_file);
                    while ((_line = _stream.ReadLine()) != null)
                    {
                        _data.Add(_line);
                    }
                    _stream.Close();
                }
                _textBox.AppendText(_data.ElementAt(_data.Count-1) + Environment.NewLine);           
            }
        }
    }
    The constructor takes two arguments: file for monitoring and text box for output. As accessing visual elements from threads is not possible, we have to use invoked methods for this.
    As you can see on every file write we have an event which executes the method called LogFileChanged() which uses the delegate to read the log file and update the text box.

    The code for the log class is extremely simple. I am using the singelton pattern for easy access in the application and I only want to have one logger.
    Code:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    using System.IO;
    
    namespace LogWatcher
    {
        /// <summary>
        /// This class uses only 1 method for writing into the log file.
        /// </summary>
        class Log
        {
            /// <summary>
            /// Log file is written by the stream writer.
            /// </summary>
            private StreamWriter _stream;
    
            /// <summary>
            /// Hard codes log file.
            /// </summary>
            private string _file = "LogWatcher.log";
    
            /// <summary>
            /// For thread synchronized file access.
            /// </summary>
            private System.Object _lockThis = new System.Object();
    
            #region Singleton
            /// <summary>
            /// Instance holding variable for the singleton pattern.
            /// </summary>
            private static Log _instance;
    
            private Log() 
            {
    
            }
    
            public static Log Instance
            {
                get
                {
                    if (_instance == null)
                    {
                        _instance = new Log();
                    }
                    return _instance;
                }
            }
            #endregion
    
            /// <summary>
            /// Synchronized writing to the file.
            /// </summary>
            /// <param name="message"></param>
            public void L(string message) 
            {
                lock (_lockThis)
                {
                    _stream = File.AppendText(_file);
                    _stream.WriteLine(DateTime.Now + ": " + message);
                    _stream.Flush();
                    _stream.Close();
                }
            }
        }
    }
    Notice that several threads will be accessing the log file so we have to synchronize them, see "lock" in the code.

    The last important class is my testing class called FileChanger for demonstration.
    Code:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    using System.IO;
    using System.Threading;
    
    namespace LogWatcher
    {
        /// <summary>
        /// To show how the log file monitor works we have to write something to the log file. Uses the log class.
        /// </summary>
        class FileChanger
        {   
            /// <summary>
            /// Random lines for the log file.
            /// </summary>
            private List<string> _rndline;
    
            /// <summary>
            /// Randomizer for random lines.
            /// </summary>
            private Random _random;
    
            /// <summary>
            /// For sleeping between writes.
            /// </summary>
            private int _mseconds = 0;
    
            /// <summary>
            /// Randomized line length.
            /// </summary>
            private int _tlenght = 0;
    
            /// <summary>
            /// For holding current line elements.
            /// </summary>
            private int _element = 0;
    
            /// <summary>
            /// This appended to the file.
            /// </summary>
            private string _text = "";
    
            /// <summary>
            /// Our log file.
            /// </summary>
            private string _file = "";
    
            /// <summary>
            /// For thread synchronized file access.
            /// </summary>
            private System.Object _lockThis = new System.Object();
    
            public FileChanger(int mseconds, string file) 
            {
                /* setting vars */
                _file = file;
                _mseconds = mseconds;
    
                /* instantiate objects */
                _rndline = new List<string>();
                _random = new Random();
    
                char start = Char.Parse("a");
                char end = Char.Parse("z");
                /* fill possible chars */
                for (char i = start; i <= end; i++) 
                {
                    _rndline.Add(i.ToString());
                }
            }
    
            /// <summary>
            /// Build up random line and log it.
            /// </summary>
            public void WriteLine() 
            {
                while (true)
                {
                    _tlenght = _random.Next(1, _rndline.Count);
    
                    for (int i = 1; i <= _tlenght; i++)
                    {
                        _element = _random.Next(0, _tlenght);
                        _text = _text + _rndline.ElementAt(_element);
                    }
    
                    lock (_lockThis)
                    {
                        Log.Instance.L(_text);
                        
                    }
                    _text = "";
                    Thread.Sleep(_mseconds);
                }
            }
        }
    }
    The WriteLine() method is started in a thread which is created in the Form1 class. See below.

    Code:
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    
    using System.IO;
    using System.Threading;
    
    namespace LogWatcher
    {
        public partial class Form1 : Form
        {
            private LogFileMonitor  _monitor;
            private FileChanger     _changer;
            private Thread          _thread;
                    
            public Form1()
            {
                InitializeComponent();
            }
    
    
    
            private void Form1_Load(object sender, EventArgs e)
            {
                _monitor =  new LogFileMonitor("LogWatcher.log", textBox1);
                _changer =  new FileChanger(500, "LogWatcher.log");
                _thread =   new Thread(_changer.WriteLine);
    
                _thread.Start();
            }
    
            private void Form1_FormClosed(object sender, FormClosedEventArgs e)
            {
                _thread.Abort();
            }
        }
    }
    Of course we could make this whole thing much easier, for example the L method from the Log class could just write directly to the text box and to the log file at the same time. Nevertheless I wanted to use the SystemFileWatcher class and use events ;-)

    The code above is not well commented in this thread, I know, I am too lazy. Have fun using and modifying this for your needs.

    To the gurus: Critical comments are extremely welcome. I am sure Apoc has better solutions.
    To the noobs like myself: You may ask every stupid question ;-)
    Attached Files Attached Files
    Last edited by Viano; 01-17-2010 at 10:15 AM.
    Viano

    [Guide] How I handle log files!

Similar Threads

  1. [GUIDE] ...How To Excute SQL FILES In To Your Database...
    By Followup in forum WoW EMU Guides & Tutorials
    Replies: 10
    Last Post: 08-01-2020, 08:04 AM
  2. [Guide] How to handle beggers
    By manowarlock in forum World of Warcraft Guides
    Replies: 23
    Last Post: 11-08-2008, 09:55 PM
All times are GMT -5. The time now is 01:22 AM. Powered by vBulletin® Version 4.2.3
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2024 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search