SECI  1
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Properties Events
DatabaseLogger.cs
Go to the documentation of this file.
1 using System;
2 using System.Collections;
3 using System.Collections.Generic;
4 using System.Text;
5 using System.Threading;
6 
7 namespace Seci.Helpers
8 {
16  public static class DatabaseLogger
17  {
18  private static DatabaseWriter _dbWriter;
19  private static Queue<LogInfo> _logQueue;
20  private static Queue<CurrValInfo> _currValsQueue;
21  private static Thread _dbWriterThread;
22 
26  public static void StartLogger()
27  {
28  _logQueue = new Queue<LogInfo>();
29  _currValsQueue = new Queue<CurrValInfo>();
30  _dbWriter = new DatabaseWriter(_logQueue, _currValsQueue);
31  _dbWriterThread = new Thread(_dbWriter.ThreadRun);
32  _dbWriterThread.Start();
33  }
34 
41  public static void AddLogValue(String time, String blockname, String value)
42  {
43  try
44  {
45  LogInfo info = new LogInfo(time, blockname, value);
46 
47  if (value == Definitions.BlockInfo.ErrorString)
48  {
49  info = new LogInfo(time, blockname, "NAN");
50  }
51 
52  lock (((ICollection)_logQueue).SyncRoot)
53  {
54  _logQueue.Enqueue(info);
55  }
56 
57  //Seci.Helpers.MessageLogger.WriteMessage("DatabaseLogger:AddLogValue", "Queue count = " + _logQueue.Count);
58  }
59  catch (Exception err)
60  {
61  Seci.Helpers.ErrorLogger.SeciError("AddLogValue", err);
62  }
63  }
64 
71  public static void AddCurrentValue(String blockname, String value, String setpoint)
72  {
73  try
74  {
75  if (setpoint == null)
76  {
77  setpoint = "";
78  }
79 
80  CurrValInfo info = new CurrValInfo(blockname, value, setpoint);
81 
82  lock (((ICollection)_currValsQueue).SyncRoot)
83  {
84  _currValsQueue.Enqueue(info);
85  }
86 
87  //Seci.Helpers.MessageLogger.WriteMessage("DatabaseLogger:AddCurrentValue", "Queue count = " + _currValsQueue.Count);
88  }
89  catch (Exception err)
90  {
91  Seci.Helpers.ErrorLogger.SeciError("AddCurrentValue", err);
92  }
93  }
94 
98  public static void StopDatabaseLoggerThread()
99  {
100  _dbWriter.RequestThreadExit();
101  }
102 
107  public static void LogConfigName(String config)
108  {
109  _dbWriter.WriteConfigName(config);
110  }
111 
112  public static void WriteBlockDetails()
113  {
114  BlockDictionary blocks = Managers.BlockMgr.GetBlocksClone();
115 
116  for (int i = 0; i < blocks.Count; ++i)
117  {
118  //Enabled = 1, Runcontrol = 2, LogAtBegin = 4, LogAtEnd = 8
119  int options = 0;
120 
121  if (blocks[i].BlockEnabled) options += 1;
122  if (blocks[i].UnderRunControl) options += 2;
123  if (blocks[i].LogChangesOnly || blocks[i].LogChangesTolerance) options += 12;
124 
125  //Check for nulls
126  String read = "";
127  String write = "";
128  String go = "";
129  String nexusname = "";
130  String units = "";
131  String curr = "";
132  String set = "";
133 
134  if (blocks[i].ReadControl != null && blocks[i].ReadControl.EndsWith(")")) read = blocks[i].ReadControl.Substring(0, blocks[i].ReadControl.LastIndexOf('(') - 1);
135  if (blocks[i].WriteControl != null && blocks[i].WriteControl.EndsWith(")")) write = blocks[i].WriteControl.Substring(0, blocks[i].WriteControl.LastIndexOf('(') - 1);
136  if (blocks[i].GoButton != null && blocks[i].GoButton.EndsWith(")")) go = blocks[i].GoButton.Substring(0, blocks[i].GoButton.LastIndexOf('(') - 1);
137  if (blocks[i].NexusName != null) nexusname = blocks[i].NexusName;
138  if (blocks[i].BlockUnits != null) units = blocks[i].BlockUnits;
139  if (blocks[i].CurrentValue != null) curr = blocks[i].CurrentValue;
140  if (blocks[i].SetPointValue != null) set = blocks[i].SetPointValue;
141 
142  _dbWriter.WriteBlockDetails(blocks[i].BlockName, set, blocks[i].ParentVI, read,
143  write, go, options, nexusname, blocks[i].LowerLimit, blocks[i].UpperLimit, units, curr);
144 
145  //if (!String.IsNullOrEmpty(blocks[i].Alias))
146  //{
147  // _dbWriter.WriteBlockDetails(blocks[i].Alias, set, blocks[i].ParentVI, read,
148  // write, go, options, nexusname, blocks[i].LowerLimit, blocks[i].UpperLimit, units, curr);
149  //}
150  }
151  }
152 
153  public static void ClearQueues()
154  {
155  try
156  {
157  lock (((ICollection)_currValsQueue).SyncRoot)
158  {
159  _currValsQueue.Clear();
160  }
161 
162  lock (((ICollection)_logQueue).SyncRoot)
163  {
164  _logQueue.Clear();
165  }
166  }
167  catch
168  {
169  }
170  }
171 
175  public static void CloseDatabase()
176  {
177  _dbWriter.CloseDatabase();
178  }
179  }
180 
185  {
186  private Boolean _inError = false;
187  private DateTime _firstErrorTime;
188  private selogcomLib.selog _dbCom = new selogcomLib.selog();
189  private Boolean _exitThread;
190 
191  private Queue<LogInfo> _logQueue;
192  private List<String> _logTimes = new List<string>();
193  private List<String> _logNames = new List<string>();
194  private List<String> _logValues = new List<string>();
195 
196  private Queue<CurrValInfo> _currValsQueue;
197  private List<String> _currValsNames = new List<string>();
198  private List<String> _currValsValues = new List<string>();
199  private List<String> _currValsSetpoints = new List<string>();
200 
206  public DatabaseWriter(Queue<LogInfo> logqueue, Queue<CurrValInfo> currvalsqueue)
207  {
208  _logQueue = logqueue;
209  _currValsQueue = currvalsqueue;
210  }
211 
215  public void RequestThreadExit()
216  {
217  _exitThread = true;
218  }
219 
223  public void ThreadRun()
224  {
225  while (!_exitThread)
226  {
227  try
228  {
229  //Give the queues time to fill up
230  Thread.Sleep(1000);
231 
232  _logTimes.Clear();
233  _logNames.Clear();
234  _logValues.Clear();
235 
236  _currValsNames.Clear();
237  _currValsValues.Clear();
238  _currValsSetpoints.Clear();
239 
240  //Get values from log queue
241  lock (((ICollection)_logQueue).SyncRoot)
242  {
243  //Keep going until the queue is empty or the number of values to log exceeds 50 items
244  while (_logQueue.Count > 0)// && _logNames.Count < 50)
245  {
246  LogInfo temp = _logQueue.Dequeue();
247 
248  if (temp != null && !String.IsNullOrEmpty(temp.Time) && !String.IsNullOrEmpty(temp.Name) && !String.IsNullOrEmpty(temp.Value))
249  {
250  _logTimes.Add(temp.Time);
251  _logNames.Add(temp.Name);
252  _logValues.Add(temp.Value);
253  }
254  }
255  }
256 
257  //Write to database here using SELogValues
258  int runNumber;
259  if (_logTimes.Count > 0 && int.TryParse(Seci.Standard.Dae.RunNumber, out runNumber))
260  {
261  lock (_dbCom)
262  {
263  _dbCom.SELogValues(runNumber, "SECI", _logTimes.ToArray(), _logNames.ToArray(), _logValues.ToArray());
264  }
265  }
266 
267  //Get values from current values queue
268  lock (((ICollection)_currValsQueue).SyncRoot)
269  {
270  //Keep going until the queue is empty
271  while (_currValsQueue.Count > 0)
272  {
273  CurrValInfo temp = _currValsQueue.Dequeue();
274  _currValsNames.Add(temp.Name);
275  _currValsValues.Add(temp.Value);
276  _currValsSetpoints.Add(temp.Setpoint);
277  }
278  }
279 
280  //Write to database here using SESetBlockValues and SESetBlockSetpoints
281  lock (_dbCom)
282  {
283  if (_currValsNames.Count > 0)
284  {
285  _dbCom.SESetBlockValues(_currValsNames.ToArray(), _currValsValues.ToArray());
286  _dbCom.SESetBlockSetpoints(_currValsNames.ToArray(), _currValsSetpoints.ToArray());
287  }
288  }
289 
290  //No errors
291  _inError = false;
292  }
293  catch (Exception err)
294  {
295  //If it is a first time error then log, otherwise only log an error reminder every ten minutes.
296  if (!_inError)
297  {
298  _inError = true;
299  _firstErrorTime = DateTime.UtcNow;
300  Helpers.ErrorLogger.SeciError("DatabaseWriter ThreadRun", err);
301  }
302  else
303  {
304  TimeSpan diff = DateTime.UtcNow - _firstErrorTime;
305  if (diff >= TimeSpan.FromMinutes(10))
306  {
307  Helpers.ErrorLogger.SeciError("DatabaseWriter ThreadRun - still in error", err);
308  _firstErrorTime = DateTime.UtcNow;
309  }
310  }
311  }
312  }
313  }
314 
319  public void WriteConfigName(String name)
320  {
321  try
322  {
323  lock (_dbCom)
324  {
325  _dbCom.SENewSECIConfig(name);
326  }
327  }
328  catch (Exception err)
329  {
330  //Log error and hope it works next time!
331  Helpers.ErrorLogger.SeciError("WriteConfigName", err);
332  }
333  }
334 
350  public void WriteBlockDetails(String name, String setpoint, String vi, String readcontrol, String setcontrol, String buttoncontrol,
351  int options, String nexusname, Double lowlimit, Double highlimit, String units, String currentvalue)
352  {
353  try
354  {
355  lock (_dbCom)
356  {
357  //Temporary workround
358  Single low = correctLimit((Single)lowlimit);
359  Single high = correctLimit((Single)highlimit);
360 
361  _dbCom.SESetBlockDetails(name, setpoint, vi, readcontrol, setcontrol, buttoncontrol, options, nexusname, low, high, units, currentvalue);
362  }
363  }
364  catch (Exception err)
365  {
366  Seci.Helpers.ErrorLogger.SeciError("WriteBlockDetails", err);
367  }
368  }
369 
370  private static Single correctLimit(Single value)
371  {
372  if (Single.IsNegativeInfinity(value))
373  {
374  value = Single.MinValue;
375  }
376  else if (Single.IsPositiveInfinity(value))
377  {
378  value = Single.MaxValue;
379  }
380  return value;
381  }
382 
386  public void CloseDatabase()
387  {
388  try
389  {
390  lock (_dbCom)
391  {
392  _dbCom.SEClose();
393  }
394  }
395  catch
396  {
397 
398  }
399  }
400  }
401 
405  class LogInfo
406  {
407  public String Name { get; private set; }
408  public String Time { get; private set; }
409  public String Value { get; private set; }
410 
417  public LogInfo(String time, String name, String value)
418  {
419  Name = name;
420  Time = time;
421  Value = value;
422  }
423  }
424 
429  {
430  public String Name { get; private set; }
431  public String Value { get; private set; }
432  public String Setpoint { get; private set; }
433 
440  public CurrValInfo(String name, String value, String setpoint)
441  {
442  Name = name;
443  Value = value;
444  Setpoint = setpoint;
445  }
446  }
447 }
static void CloseDatabase()
Close the database connection
LogInfo(String time, String name, String value)
Constructor
CurrValInfo(String name, String value, String setpoint)
Constructor
static Queue< CurrValInfo > _currValsQueue
static void AddLogValue(String time, String blockname, String value)
Add a log value to the queue
static DatabaseWriter _dbWriter
void RequestThreadExit()
Request that the thread should exit
void CloseDatabase()
Close the database connection
void WriteConfigName(String name)
Write the configuration name to the database
static void StopDatabaseLoggerThread()
Stop the logging thread
static void AddCurrentValue(String blockname, String value, String setpoint)
Add a current value to the queue
A small class for storing current value information
A small class for storing log information
static void LogConfigName(String config)
Log the configuration name
This class is used performs the following tasks:
static Queue< LogInfo > _logQueue
static Single correctLimit(Single value)
Specialised version of the Dictionary class which can be converted to XML. Also has some additional s...
static void StartLogger()
Starts the logger thread.
This class does the actual logging to the database
void ThreadRun()
This is the method that is run on a separate thread
void WriteBlockDetails(String name, String setpoint, String vi, String readcontrol, String setcontrol, String buttoncontrol, int options, String nexusname, Double lowlimit, Double highlimit, String units, String currentvalue)
This method is used to write the details about the block to the database.
Queue< CurrValInfo > _currValsQueue
DatabaseWriter(Queue< LogInfo > logqueue, Queue< CurrValInfo > currvalsqueue)
The constructor