1 module puppeteer.logging.multifile_gnuplot_crafter_logger; 2 3 import test.puppeteer.logging.multifile_gnuplot_crafter_logger_test : test; 4 mixin test; 5 6 import puppeteer.logging.i_puppeteer_logger; 7 import puppeteer.logging.basic_logger; 8 9 import gnuplot_crafter.multithreaded.singlevar_crafter; 10 11 import std.conv; 12 import std.stdio; 13 14 import core.atomic; 15 16 public shared class MultifileGnuplotCrafterLogger(size_t flushCounter) : IPuppeteerLogger 17 { 18 string dataFilesPath; 19 SingleVarCrafter!(float)*[string] crafters; 20 size_t[string] counters; 21 22 this(string dataFilesPath) 23 { 24 //TODO: check for valid path 25 this.dataFilesPath = dataFilesPath; 26 } 27 28 ~this() 29 { 30 debug writeln("Destroying logger"); 31 //Delete all allocated structs 32 foreach(shared SingleVarCrafter!(float)* crafterPtr; crafters) 33 { 34 debug writeln("Finalizing crafter"); 35 crafterPtr.__dtor(); // Destroy does not call the destructor :( 36 debug writeln("Destructor called"); 37 destroy(crafterPtr); 38 debug writeln("Crafter destroyed"); 39 } 40 crafters.clear(); 41 debug writeln("Logger destroyed"); 42 } 43 44 private string getPathForSensorData(string sensorName) 45 { 46 return dataFilesPath ~ sensorName ~ ".dat"; 47 } 48 49 public void logSensor(long timeMs, string sensorName, string readValue, string adaptedValue) 50 { 51 auto crafterPtr = sensorName in crafters; 52 53 if(crafterPtr !is null) 54 { 55 crafters[sensorName].put(to!float(timeMs), to!float(adaptedValue)); 56 57 auto counterPtr = sensorName in counters; 58 59 atomicOp!"+="(*counterPtr, 1); 60 if(*counterPtr >= flushCounter) 61 { 62 crafters[sensorName].flush(); 63 *counterPtr = 0; 64 } 65 } 66 else 67 { 68 crafters[sensorName] = new shared SingleVarCrafter!float(getPathForSensorData(sensorName), false); 69 crafters[sensorName].put(to!float(timeMs), to!float(adaptedValue)); 70 counters[sensorName] = 1; 71 } 72 } 73 74 public void logInfo(long timeMs, string info) 75 { 76 //Do nothing!! 77 } 78 }