Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

A simple logger


  • Please log in to reply
6 replies to this topic

#1 stotech

stotech

    Advanced Member

  • Members
  • PipPipPip
  • 143 posts
  • LocationAustralia

Posted 06 September 2012 - 11:48 AM

Hi Everyone,
I’m trying to make a simple logger for my Netduino Plus. I’ve looked at heaps of different examples and looked over the forums for days but haven’t found any that suit. So I’m posting for help.
I’m trying to make a class that has three functions.
Log.Write(string text)
Log.Read()
Log.Trim(int lines)

Below is what I’ve got so far but it’s obviously bogus. I think I’m on the right track but I might be way off. I think I could pull it off if it wasn’t such a large file that I can’t read it all into memory. Because I’m not using a real time clock, I don’t have a way to purge the file except from by line number. I really need the log to always stay at 200 lines long. I want Log.Trim to delete any lines past 200 and Log.Write to add to the file at the beginning. And to top it all off I need Log.Read to return it to a single string one line at a time so I can view it on the webserver. Without using all the memory.
Thanks in Advance.

using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.NetduinoPlus;
using System.IO;

namespace WebserverTest
{
    class Log
    {
        public static string read()
        {
                int counter = 0;
                string line;

                System.IO.StreamReader file = new System.IO.StreamReader(@"\SD\Log.txt");
                while ((line = file.ReadLine()) != null)
                {
                    System.Console.WriteLine(line);  //I know i've got this wrong but i'm a noob!
                    counter++;
                }
                file.Close();
                Debug.Print("There were " + counter.ToString() + " lines read");
            return line;
        }

        public static void Write(string text)
        {
            Trim(200);

            using (var filestream = new FileStream(@"\SD\Log.txt", FileMode.Append))
            {
                StreamWriter sw = new StreamWriter(filestream);
                sw.BaseStream.Seek(0, SeekOrigin.Begin);
                sw.Write(" File Write Operation Starts : \n");
                sw.WriteLine(" First Line : Data is first line \n");
                sw.WriteLine(" This is next line in the text file. \n ");
                sw.Flush();
                sw.Close();
            }

        }

        public static void Trim(int lines)
        {
            string line = null; 
            int line_number = 0; 
            int line_to_delete = lines;

            using (StreamReader reader = new StreamReader(@"\SD\Log.txt"))
                {
                    using (StreamWriter writer = new StreamWriter(@"\SD\Temp.txt")) 
                    { 
                        while ((line = reader.ReadLine()) != null) 
                        { 
                            line_number++; 
                            if (line_number == line_to_delete)                 
                                continue; 
                            
                            writer.WriteLine(line); 
                        } 
                    }
                }
            SetUp.confirm();
            File.Delete(@"\SD\Log.txt");
            File.Move(@"\SD\Temp.txt", @"\SD\Log.txt"); 
        }
    }
}



#2 Victor M.

Victor M.

    Advanced Member

  • Members
  • PipPipPip
  • 39 posts
  • LocationRio de Janeiro, Brazil

Posted 06 September 2012 - 01:38 PM

Hi Grant,
I'm testing your code, but what is the objective of this line:
SetUp.confirm();

It's don't work.

Victor

#3 stotech

stotech

    Advanced Member

  • Members
  • PipPipPip
  • 143 posts
  • LocationAustralia

Posted 06 September 2012 - 09:35 PM

Thanks mate. Setup.confirm is a little class that blinks the LED a few times. that's all. I put it all through my code to debug stuff.

#4 JerseyTechGuy

JerseyTechGuy

    Advanced Member

  • Members
  • PipPipPip
  • 870 posts

Posted 07 September 2012 - 11:47 AM

Two mistakes I noticed. In two places you have a space in "\SD \Log.txt" after the SD.

#5 stotech

stotech

    Advanced Member

  • Members
  • PipPipPip
  • 143 posts
  • LocationAustralia

Posted 09 September 2012 - 12:52 PM

I'm Still completely Stuck here but I'm getting somewhere now with log.print.
This is what i've got and it works first run through but not second. Can someone help with this and it's got to be made thread safe as well.

public static void Print(string text)
        {
            string holding = "";
            SetUp.confirm(2, 4);
            Thread.Sleep(1000);
            if (File.Exists(@"\SD\Log.txt"))
            {
                using (StreamReader SR = new StreamReader(@"\SD\Log.txt"))
                {
                    holding = SR.ReadToEnd();
                    SR.Close();
                }
                if (!File.Exists(@"\SD\Temp.txt"))
                {
                    File.Create(@"\SD\Temp.txt");
                }
                using (StreamWriter SW = new StreamWriter(@"\SD\Temp.txt", false))
                {
                    SW.WriteLine(text);
                    SW.WriteLine(holding);
                    SW.Flush();
                    SW.Close();
                }
            }
            else
            {
                File.Create(@"\SD\Log.txt");
                Print(text);
            }
            Thread.Sleep(1000);
            SetUp.confirm(2, 6);
            File.Delete(@"\SD\Log.txt");
            Thread.Sleep(1000);
            File.Move(@"\SD\Temp.txt", @"\SD\Log.txt");
            SetUp.confirm(2, 8);
            Thread.Sleep(1000);
        }


#6 stotech

stotech

    Advanced Member

  • Members
  • PipPipPip
  • 143 posts
  • LocationAustralia

Posted 10 September 2012 - 10:58 AM

ok. This is what i've got so far and it works for the first ten minutes or so and breaks at random. The files aren't readable on a PC either. even when they're working on the netduino.

Help Please.

using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.IO;
using SecretLabs.NETMF.IO;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.NetduinoPlus;


namespace WebserverTest
{
    class Log
    {
        private static Object thisLock = new Object();
        public static int lenth = 200;

        public static string Read()
        {
            lock (thisLock)
            {
                string sContent = "";

                if (File.Exists(@"\SD\Logs\Log.txt"))
                {
                    StreamReader reader = new StreamReader(new FileStream(@"\SD\Logs\Log.txt", FileMode.Open, FileAccess.Read));
                    sContent = reader.ReadToEnd();
                    reader.Close();
                    Log.Print("Memory: " + Microsoft.SPOT.Debug.GC(false).ToString());
                }
                return sContent;
            }
        }

        public static void Print(string text)
        {
            lock (thisLock)
            {
                Debug.Print(text);
                Trim();
                int delay = 250;
                string holding = "";
                Thread.Sleep(delay);

                if (!Directory.Exists(@"\SD\Logs"))
                {
                    Directory.CreateDirectory(@"\SD\Logs");
                    Thread.Sleep(delay);
                }
                if (File.Exists(@"\SD\Logs\Log.txt"))
                {
                    using (StreamReader SR = new StreamReader(@"\SD\Logs\Log.txt"))
                    {
                        holding = SR.ReadToEnd();
                        SR.Close();
                    }
                }
                if (File.Exists(@"\SD\Logs\Temp.txt"))
                {
                    File.Delete(@"\SD\Logs\Temp.txt");
                    Thread.Sleep(delay);
                }
                using (StreamWriter SW = new StreamWriter(@"\SD\Logs\Temp.txt", false))
                {
                    Thread.Sleep(delay);
                    SW.WriteLine(text);
                    SW.WriteLine(holding);
                    SW.Close();
                }

                Thread.Sleep(delay);
                File.Delete(@"\SD\Logs\Log.txt");
                Thread.Sleep(delay);
                File.Move(@"\SD\Logs\Temp.txt", @"\SD\Logs\Log.txt");
                SetUp.confirm(1, 8);
            }
        }

        public static void Trim()
        {
            int linecount = 0;
            if (File.Exists(@"\SD\Logs\Log.txt"))
            {
                using (StreamReader r = new StreamReader(@"\SD\Logs\Log.txt"))
                {
                    string line;
                    while ((line = r.ReadLine()) != null)
                    {
                        linecount++;
                    }
                }
            }

            if (File.Exists(@"\SD\Logs\Log.txt") & linecount >= lenth)
            {
                string line = null;
                int delay = 250;
                int line_number = 0;
                int line_to_delete = lenth;

                using (StreamReader reader = new StreamReader(@"\SD\Logs\Log.txt"))
                {
                    using (StreamWriter writer = new StreamWriter(@"\SD\Logs\Temp2.txt", false))
                    {
                        while ((line = reader.ReadLine()) != null)
                        {
                            line_number++;
                            if (line_number == line_to_delete)
                                continue;
                            writer.WriteLine(line);
                        }
                    }
                }
                Thread.Sleep(delay);
                File.Delete(@"\SD\Logs\Log.txt");
                Thread.Sleep(delay);
                File.Move(@"\SD\Logs\Temp2.txt", @"\SD\Logs\Log.txt");
                SetUp.confirm(1, 8);
            }
        }
    }
}



#7 dustmouse

dustmouse

    Advanced Member

  • Members
  • PipPipPip
  • 31 posts
  • LocationEdgewater, CO

Posted 13 March 2014 - 05:02 AM

I know this is waay late, but I was able to get a file logger working with the following code.  It can be configured to do rolling logs or just purge the log when it gets to a certain size and start filling it again.  

 

The idea is that there is only one instance of the logger (singleton) to avoid problems with different instances trying to write to the same location concurrently.  It's supposed to be thread-safe, but I haven't really tested that aspect of it yet.

    public class FileLogger : ILogger
    {
        private static FileLogger _instance;
        private static object lockObject = new Object();

        #region Constructors

        private FileLogger(string filePath, long maxFileSize, bool isRolling)
        {
            this.FilePath = filePath;
            this.MaxFileSize = maxFileSize;
            this.IsRolling = isRolling;  
        }

        #endregion

        #region Public Properties

        public static FileLogger Instance
        {
            get
            {
                if (FileLogger._instance == null)
                    throw new Exception("File logger has not been instantiated.");

                return FileLogger._instance;
            }
        }

        public static bool IsInstantiated { get; private set; }

        public string FilePath { get; private set; }

        public long MaxFileSize { get; private set; }

        public bool IsRolling { get; private set; }

        #endregion

        #region ILogger Members

        public void Log(Severity severity, string message)
        {
            if (this.FilePath == null || this.FilePath.Trim().Length == 0)
                throw new Exception("Must specify file path for logging.");

            lock (FileLogger.lockObject)
            {
                if (File.Exists(this.FilePath))
                {
                    var fileInfo = new FileInfo(this.FilePath);

                    if (this.MaxFileSize != -1 && fileInfo.Length > this.MaxFileSize)
                    {
                        if (!this.IsRolling)
                            File.Delete(this.FilePath);
                        else
                            this.rollFile();
                    }
                }

                using (var fileStream = new FileStream(this.FilePath, FileMode.Append))
                using (var streamWriter = new StreamWriter(fileStream))
                    streamWriter.WriteLine(DateTime.Now.ToString() + " - " +
                        severity.ToString().ToUpper() + " - " + message);
            }
        }

        #endregion

        #region Public Methods

        public static FileLogger Instantiate(
            string filePath, long maxFileSize = -1, bool isRolling = false)
        {
            if (FileLogger.IsInstantiated)
                throw new Exception("File logger has already been instantiated.");

            lock (FileLogger.lockObject)
            {
                FileLogger._instance =
                    new FileLogger(filePath, maxFileSize, isRolling);

                FileLogger.IsInstantiated = true;
            }

            return FileLogger._instance;
        }

        #endregion

        #region Private Methods

        private void rollFile()
        {
            if (!File.Exists(this.FilePath))
                throw new Exception(
                    "Failed to roll log file.  '" + this.FilePath + "' does not exist.");

            int fileExtensionIndex = this.FilePath.LastIndexOf('.');
            string rolledFilePath = this.FilePath.Substring(0, fileExtensionIndex) +
                "_" + Guid.NewGuid().ToString() + 
                this.FilePath.Substring(fileExtensionIndex, this.FilePath.Length - fileExtensionIndex);
            
            File.Move(this.FilePath, rolledFilePath);
        }

        #endregion
    }

Check out my Netduino projects on GitHub.





0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.