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