Utilities/Logger.cs
author moel.mich
Sun, 11 Aug 2013 21:26:56 +0000
changeset 420 46c056e76130
child 421 055a9ec117d2
permissions -rw-r--r--
Added a first data logging implementation.
     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 ISensor[] sensors;
    29 
    30     public Logger(IComputer computer) {
    31       this.computer = computer;
    32       this.computer.HardwareAdded += HardwareAdded;
    33       this.computer.HardwareRemoved += HardwareRemoved;    
    34     }
    35 
    36     private void HardwareRemoved(IHardware hardware) {
    37       hardware.SensorRemoved -= SensorRemoved;
    38       foreach (ISensor sensor in hardware.Sensors)
    39         SensorRemoved(sensor);
    40       foreach (IHardware subHardware in hardware.SubHardware)
    41         HardwareRemoved(subHardware);
    42     }
    43 
    44     private void HardwareAdded(IHardware hardware) {
    45       hardware.SensorRemoved += SensorRemoved;
    46       foreach (IHardware subHardware in hardware.SubHardware)
    47         HardwareAdded(subHardware);
    48     }
    49 
    50     private void SensorRemoved(ISensor sensor) {
    51       for (int i = 0; i < sensors.Length; i++) {
    52         if (sensor == sensors[i])
    53           sensors[i] = null;
    54       }
    55     }
    56 
    57     private static string GetFileName(DateTime date) {
    58       return AppDomain.CurrentDomain.BaseDirectory +
    59         Path.DirectorySeparatorChar + string.Format(fileNameFormat, date);
    60     }
    61 
    62     private void AddSensorRemovedHandler() {
    63       for (int i = 0; i < sensors.Length; i++) {
    64         ISensor sensor = sensors[i];
    65         int index = i;
    66         SensorEventHandler handler = null;        
    67         handler = s => {
    68           if (s != sensor) 
    69             return;
    70 
    71           sensors[index] = null;
    72           sensor.Hardware.SensorRemoved -= handler;          
    73         };
    74         sensor.Hardware.SensorRemoved += handler;
    75       }
    76     }
    77 
    78     private bool OpenExistingLogFile() {
    79       if (!File.Exists(fileName))
    80         return false;
    81 
    82       string[] identifiers;
    83       try {
    84         String line;
    85         using (StreamReader reader = new StreamReader(fileName)) 
    86           line = reader.ReadLine(); 
    87        
    88         if (string.IsNullOrEmpty(line))
    89           return false;
    90         
    91         identifiers = line.Split(',').Skip(1).ToArray();
    92       } catch {
    93         return false;
    94       }
    95 
    96       if (identifiers.Length == 0)
    97         return false;
    98 
    99       sensors = new ISensor[identifiers.Length];
   100       SensorVisitor visitor = new SensorVisitor(sensor => {
   101         for (int i = 0; i < identifiers.Length; i++)
   102           if (sensor.Identifier.ToString() == identifiers[i])
   103             sensors[i] = sensor;
   104       });
   105       visitor.VisitComputer(computer);
   106       return true;
   107     }
   108 
   109     private void CreateNewLogFile() {
   110       IList<ISensor> list = new List<ISensor>();
   111       SensorVisitor visitor = new SensorVisitor(sensor => {
   112         list.Add(sensor);
   113       });
   114       visitor.VisitComputer(computer);
   115       sensors = list.ToArray();      
   116 
   117       using (StreamWriter writer = new StreamWriter(fileName, false)) {
   118         writer.Write(",");
   119         for (int i = 0; i < sensors.Length; i++) {
   120           writer.Write(sensors[i].Identifier);
   121           if (i < sensors.Length - 1)
   122             writer.Write(",");
   123           else
   124             writer.WriteLine();
   125         }
   126 
   127         writer.Write("Time,");
   128         for (int i = 0; i < sensors.Length; i++) {
   129           writer.Write('"');
   130           writer.Write(sensors[i].Name);
   131           writer.Write('"');
   132           if (i < sensors.Length - 1)
   133             writer.Write(",");
   134           else
   135             writer.WriteLine();
   136         }
   137       }
   138     }
   139 
   140     public void Log() {
   141       var now = DateTime.Now;
   142       if (day != now.Date) {
   143         day = now.Date;
   144         fileName = GetFileName(day);
   145 
   146         if (!OpenExistingLogFile())
   147           CreateNewLogFile();
   148       }
   149 
   150       using (StreamWriter writer = new StreamWriter(fileName, true)) {
   151         writer.Write(now.ToString("G", CultureInfo.InvariantCulture));
   152         writer.Write(",");
   153         for (int i = 0; i < sensors.Length; i++) {
   154           if (sensors[i] != null) {
   155             float? value = sensors[i].Value;
   156             if (value.HasValue)
   157               writer.Write(
   158                 value.Value.ToString("R", CultureInfo.InvariantCulture));
   159           }
   160           if (i < sensors.Length - 1)
   161             writer.Write(",");
   162           else
   163             writer.WriteLine();
   164         }
   165       }
   166 
   167     }
   168   }
   169 }