Utilities/Logger.cs
author moel.mich
Sun, 18 Aug 2013 21:44:08 +0000
changeset 421 055a9ec117d2
parent 420 46c056e76130
child 422 0fe7d6e91094
permissions -rw-r--r--
Fixed a few stability issues in the logging implementation. Added support for logging sensors once the reappear.
     1 /*
     2  
     3   This Source Code Form is subject to the terms of the Mozilla Public
     4   License, v. 2.0. If a copy of the MPL was not distributed with this
     5   file, You can obtain one at http://mozilla.org/MPL/2.0/.
     6  
     7 	Copyright (C) 2013 Michael Möller <mmoeller@openhardwaremonitor.org>
     8 
     9 */
    10 
    11 using System;
    12 using System.Collections.Generic;
    13 using System.Globalization;
    14 using System.IO;
    15 using System.Linq;
    16 using OpenHardwareMonitor.Hardware;
    17 
    18 namespace OpenHardwareMonitor.Utilities {
    19   public class Logger {
    20 
    21     private const string fileNameFormat = 
    22       "OpenHardwareMonitorLog-{0:yyyy-MM-dd}.csv";
    23 
    24     private readonly IComputer computer;
    25 
    26     private DateTime day = DateTime.MinValue;
    27     private string fileName;
    28     private string[] identifiers;
    29     private ISensor[] sensors;
    30 
    31     public Logger(IComputer computer) {
    32       this.computer = computer;
    33       this.computer.HardwareAdded += HardwareAdded;
    34       this.computer.HardwareRemoved += HardwareRemoved;    
    35     }
    36 
    37     private void HardwareRemoved(IHardware hardware) {
    38       hardware.SensorAdded -= SensorAdded;
    39       hardware.SensorRemoved -= SensorRemoved;
    40       foreach (ISensor sensor in hardware.Sensors)
    41         SensorRemoved(sensor);
    42       foreach (IHardware subHardware in hardware.SubHardware)
    43         HardwareRemoved(subHardware);
    44     }
    45 
    46     private void HardwareAdded(IHardware hardware) {
    47       foreach (ISensor sensor in hardware.Sensors)
    48         SensorAdded(sensor);
    49       hardware.SensorAdded += SensorAdded;
    50       hardware.SensorRemoved += SensorRemoved;
    51       foreach (IHardware subHardware in hardware.SubHardware)
    52         HardwareAdded(subHardware);
    53     }
    54 
    55     private void SensorAdded(ISensor sensor) {
    56       if (sensors == null)
    57         return;
    58 
    59       for (int i = 0; i < sensors.Length; i++) {
    60         if (sensor.Identifier.ToString() == identifiers[i])
    61           sensors[i] = sensor;
    62       }
    63     }
    64 
    65     private void SensorRemoved(ISensor sensor) {
    66       if (sensors == null)
    67         return;
    68 
    69       for (int i = 0; i < sensors.Length; i++) {
    70         if (sensor == sensors[i])
    71           sensors[i] = null;
    72       }
    73     }
    74 
    75     private static string GetFileName(DateTime date) {
    76       return AppDomain.CurrentDomain.BaseDirectory +
    77         Path.DirectorySeparatorChar + string.Format(fileNameFormat, date);
    78     }
    79 
    80     private bool OpenExistingLogFile() {
    81       if (!File.Exists(fileName))
    82         return false;
    83 
    84       try {
    85         String line;
    86         using (StreamReader reader = new StreamReader(fileName)) 
    87           line = reader.ReadLine(); 
    88        
    89         if (string.IsNullOrEmpty(line))
    90           return false;
    91         
    92         identifiers = line.Split(',').Skip(1).ToArray();
    93       } catch {
    94         identifiers = null;
    95         return false;
    96       }
    97 
    98       if (identifiers.Length == 0) {
    99         identifiers = null;
   100         return false;
   101       }
   102 
   103       sensors = new ISensor[identifiers.Length];
   104       SensorVisitor visitor = new SensorVisitor(sensor => {
   105         for (int i = 0; i < identifiers.Length; i++)
   106           if (sensor.Identifier.ToString() == identifiers[i])
   107             sensors[i] = sensor;
   108       });
   109       visitor.VisitComputer(computer);
   110       return true;
   111     }
   112 
   113     private void CreateNewLogFile() {
   114       IList<ISensor> list = new List<ISensor>();
   115       SensorVisitor visitor = new SensorVisitor(sensor => {
   116         list.Add(sensor);
   117       });
   118       visitor.VisitComputer(computer);
   119       sensors = list.ToArray();
   120       identifiers = sensors.Select(s => s.Identifier.ToString()).ToArray();
   121 
   122       using (StreamWriter writer = new StreamWriter(fileName, false)) {
   123         writer.Write(",");
   124         for (int i = 0; i < sensors.Length; i++) {
   125           writer.Write(sensors[i].Identifier);
   126           if (i < sensors.Length - 1)
   127             writer.Write(",");
   128           else
   129             writer.WriteLine();
   130         }
   131 
   132         writer.Write("Time,");
   133         for (int i = 0; i < sensors.Length; i++) {
   134           writer.Write('"');
   135           writer.Write(sensors[i].Name);
   136           writer.Write('"');
   137           if (i < sensors.Length - 1)
   138             writer.Write(",");
   139           else
   140             writer.WriteLine();
   141         }
   142       }
   143     }
   144 
   145     public void Log() {
   146       var now = DateTime.Now;
   147       if (day != now.Date || !File.Exists(fileName)) {
   148         day = now.Date;
   149         fileName = GetFileName(day);
   150 
   151         if (!OpenExistingLogFile())
   152           CreateNewLogFile();
   153       }
   154 
   155       try {
   156         using (StreamWriter writer = new StreamWriter(new FileStream(fileName,
   157           FileMode.Append, FileAccess.Write, FileShare.ReadWrite))) {
   158           writer.Write(now.ToString("G", CultureInfo.InvariantCulture));
   159           writer.Write(",");
   160           for (int i = 0; i < sensors.Length; i++) {
   161             if (sensors[i] != null) {
   162               float? value = sensors[i].Value;
   163               if (value.HasValue)
   164                 writer.Write(
   165                   value.Value.ToString("R", CultureInfo.InvariantCulture));
   166             }
   167             if (i < sensors.Length - 1)
   168               writer.Write(",");
   169             else
   170               writer.WriteLine();
   171           }
   172         }
   173       } catch (IOException) { }
   174     }
   175   }
   176 }