Changeset 152 for Evidence/DColl.cc


Ignore:
Timestamp:
01/27/10 15:28:06 (12 years ago)
Author:
ogrimm
Message:
Updates
File:
1 edited

Legend:

Unmodified
Added
Removed
  • Evidence/DColl.cc

    r151 r152  
    1111        written to the data file. Only if the new value has changed by a
    1212        minimum amout it will be added to the ring buffer.
     13  - The history buffers are written to disk at program termination and
     14    are tired to be read when adding a service.
    1315  - The command 'DColl/Log' writes the associated string to the log
    1416    file specified in the configuration.
     
    2325
    2426#include "Evidence.h"
     27
     28#include <string>
     29#include <sstream>
     30#include <vector>
     31#include <iomanip>
    2532
    2633#include <math.h>
     
    4451          double LastValue;
    4552          double MinAbsChange;
    46         } *List;
    47 
     53        };
     54        vector<struct Item> List;
     55       
    4856        DimCommand *LogCommand;
    4957               
    50     unsigned int NumItems;
    51         char *Filename;
    5258    FILE *DataFile;
    5359    FILE *LogFile;
     60        char *Filename;
    5461        float DataSizekB, LogSizekB;
    5562        int DataSizeLastUpdate, LogSizeLastUpdate;
    5663        char *DataDir;
    5764    DimService *LogSizeService, *DataSizeService, *DataFilename;
     65        string HistDir;
    5866    int HistSize;
    5967        int SizeUpdateDelay;
     
    6674    void infoHandler();
    6775    void commandHandler();
    68         void AddService(char *);
     76        void AddService(string);
    6977        float FileSize(FILE *);
    7078           
     
    8088
    8189  // Initialization to prevent freeing unallocated memory
    82   Filename = NULL;
    8390  DataFile = NULL;
    8491  LogFile = NULL;
    85   List = NULL;
     92  Filename = NULL;
     93 
    8694  LogSizeService = NULL;
    8795  DataSizeService = NULL;
     
    93101  // Request configuration data
    94102  char *Change = GetConfig(SERVER_NAME " minchange");
     103
    95104  DataDir = GetConfig(SERVER_NAME " datadir");
     105
    96106  char *Logname = GetConfig(SERVER_NAME " logfile");
     107
    97108  SizeUpdateDelay = atoi(GetConfig(SERVER_NAME " sizeupdate"));
     109
    98110  HistSize = atoi(GetConfig(SERVER_NAME " histsize"));
    99111  if (HistSize < 1) HistSize = 1; // Minimum one items
     112
     113  HistDir = GetConfig(SERVER_NAME " histdir");
    100114   
    101115  // Open log file
     
    148162
    149163  // Subscribe to list of servers at DIS_DNS
    150   AddService((char *) "DIS_DNS/SERVER_LIST");
     164  AddService("DIS_DNS/SERVER_LIST");
    151165
    152166  DimClient::sendCommand("DColl/Log", SERVER_NAME" *** Logging started ***");
     
    158172DataHandler::~DataHandler() {
    159173
    160   // Delete DIM services and command first so handlers and not called anymore
    161   for (int i=0; i<NumItems; i++) {
     174  DimClient::sendCommand("DColl/Log", SERVER_NAME" *** Logging stopped ***");
     175
     176  // Delete DIM subscriptions and command first so handlers and not called anymore
     177  for (int i=0; i<List.size(); i++) {
     178    delete List[i].DataItem;
     179  }
     180  delete LogCommand;
     181 
     182  // Save history buffers to files (replace '/' by '_')
     183  for (int i=0; i<List.size(); i++) {
     184    string Name = List[i].HistService->getName();
     185        for (int j=0; j<Name.size(); j++) if (Name[j] == '/') Name[j] = '_';
     186    FILE *File = fopen((HistDir + "/" + Name).c_str(), "wb");
     187        if (File != NULL) {
     188      fwrite(&List[i].HistPointer, sizeof(List[i].HistPointer), 1, File);
     189      fwrite(List[i].HistBuffer, sizeof(EvidenceHistoryItem), HistSize, File);
     190      fclose(File);
     191        }
    162192        delete List[i].HistService;
    163     delete List[i].DataItem;
    164193    delete[] List[i].HistBuffer;
    165194  }
    166   free(List);
    167195
    168196  delete DataFilename;
     197  delete[] Filename;
     198 
    169199  //delete LogSizeService; // These create segmentation faults?!
    170200  //delete DataSizeService;
    171 
    172   delete LogCommand;
    173   free(Filename);
    174201
    175202  // Close files
     
    203230  // If service is DIS_DNS/SERVER_LIST, subscribe to all SERVICE_LIST services
    204231  if (strcmp(Info->getName(), "DIS_DNS/SERVER_LIST") == 0) {   
    205         char *Token = strtok(Info->getString(), "+-!|@");       
     232        char *Token = strtok(Info->getString(), "@");   
    206233        while (Token != NULL) {
    207           char *Buf;
    208           if (MakeString(&Buf, "%s/SERVICE_LIST", Token) != -1) {
    209             AddService(Buf);
    210                 free(Buf);
    211           }
    212           else State(ERROR, "MakeString() failed for server %s", Token);
     234          if (isalpha(*Token) == 0) Token++; // Name can start with +,-,!
    213235         
    214           Token = strtok(NULL, "|");
    215           Token = strtok(NULL, "+-!|@");       
     236          AddService(string(Token)+"/SERVICE_LIST");     
     237         
     238          Token = strtok(NULL, "|");
     239          Token = strtok(NULL, "|@");   // ???? Why needed ?????
    216240        }       
    217241        return;
     
    221245  // Subscribe to all services (but not to commands and RPCs)
    222246  if (strstr(Info->getName(), "/SERVICE_LIST") != NULL) {
    223         char *Name = strtok(Info->getString(), "+-!|");
     247
     248        char *Name = strtok(Info->getString(), "|");
    224249        while (Name != NULL) {
    225250          char *Type = strtok(NULL, "\n");
    226251          if (Type == NULL) return; // for safety, should not happen
     252          if (isalpha(*Name) == 0) Name++; // Name can start with +,-,!
    227253      if (strstr(Type, "|CMD")==NULL && strstr(Type, "|RPC")==NULL) {
    228254                AddService(Name);
    229255          }
    230           Name = strtok(NULL, "+-!|");
     256          Name = strtok(NULL, "|");
    231257        }
    232258        return;
     
    245271        time_t Time = time(NULL);
    246272        struct tm *T = localtime(&Time);
    247        
     273        ostringstream Buf;
     274       
     275        // Generate file name from date
    248276        if(T->tm_hour >= DATE_ROLLOVER) T->tm_mday++;
    249277        if (mktime(T) == -1) State(ERROR, "mktime() failed, check filename");
    250 
    251         free(Filename);
    252         if (MakeString(&Filename, "%s/%d%02d%02d.slow", DataDir, T->tm_year+1900, T->tm_mon+1, T->tm_mday) == -1) State(FATAL, "Could not create filename, MakeString() failed");
     278        Buf << DataDir << "/" << T->tm_year+1900 << setw(2) << setfill('0') << T->tm_mon+1 << T->tm_mday << ".slow";
     279       
     280        // Copy filename to permanent buffer
     281        delete[] Filename;
     282        Filename = new char [Buf.str().size()+1];
     283        strcpy(Filename, Buf.str().c_str());
     284       
     285        // Open file
    253286        if ((DataFile = fopen(Filename, "a")) == NULL) {
    254287      State(FATAL, "Could not open data file '%s' (%s)", Filename, strerror(errno));
     
    266299  // Identify index of service
    267300  int Service; 
    268   for (Service=0; Service<NumItems; Service++) if (Info == List[Service].DataItem) break;
    269   if (Service == NumItems) return;  // Service not found
     301  for (Service=0; Service<List.size(); Service++) if (Info == List[Service].DataItem) break;
     302  if (Service == List.size()) return;  // Service not found
    270303
    271304  // If negative value for absolute change, ignore this entry
     
    360393// Add service to watch list
    361394//
    362 void DataHandler::AddService(char *Name) {
     395void DataHandler::AddService(string Name) {
    363396
    364397  // Do not subscribe to history services (otherwise infinite loop)
    365   if (strstr(Name, ".hist") != NULL) return;
     398  if (Name.find(".hist") != string::npos) return;
    366399
    367400  // Check if already subscribed to this service
    368   for (int i=0; i<NumItems; i++) {
    369         if(strcmp(Name, List[i].DataItem->getName()) == 0) return;
    370   }
    371 
    372   // Increase capacity of item list                     
    373   struct Item *New = (struct Item *) realloc(List, (NumItems+1)*sizeof(struct Item));
    374   if (New != NULL) List = New;
    375   else {
    376         State(ERROR, "Could not allocate memory for item list, service '' not added (%s)", Name, strerror(errno));
    377         return;
    378   }
    379  
     401  for (int i=0; i<List.size(); i++) {
     402        if (Name == List[i].DataItem->getName()) return;
     403  }
     404 
     405  // Create new entry in item list
     406  struct Item New;
     407
    380408  // Set minimum required change by comparing to regular expressions
    381   List[NumItems].MinAbsChange = 0;
     409  New.MinAbsChange = 0;
    382410  for (int i=0; i<RegExCount; i++) {
    383     if (regexec(&RegEx[i], Name, (size_t) 0, NULL, 0) == 0) {
    384           List[NumItems].MinAbsChange = MinChange[i];
    385         }
    386   }
    387  
    388   List[NumItems].LastValue = DBL_MAX;
    389                
     411    if (regexec(&RegEx[i], Name.c_str(), (size_t) 0, NULL, 0) == 0) {
     412          New.MinAbsChange = MinChange[i];
     413        }
     414  }
     415               
    390416  // Create history service
    391   List[NumItems].HistBuffer = new struct EvidenceHistoryItem [HistSize];
    392   memset(List[NumItems].HistBuffer, 0, HistSize*sizeof(EvidenceHistoryItem));
    393   List[NumItems].HistPointer = 0;
    394 
    395   char *Buf;
    396   if (MakeString(&Buf, "%s.hist", Name) == -1) {
    397     State(ERROR, "Could not create history service for '%s', MakeString() failed", Name);
    398   }
    399   else {
    400         List[NumItems].HistService = new DimService (Buf, (char *) "C",
    401                                           List[NumItems].HistBuffer, HistSize*sizeof(EvidenceHistoryItem));
    402     free(Buf);
    403   }
    404 
     417  New.HistBuffer = new struct EvidenceHistoryItem [HistSize];
     418  memset(New.HistBuffer, 0, HistSize*sizeof(EvidenceHistoryItem));
     419  New.HistPointer = 0;
     420  New.LastValue = DBL_MAX;
     421  New.HistService = new DimService ((Name+".hist").c_str(), (char *) "C",
     422                                          New.HistBuffer, HistSize*sizeof(EvidenceHistoryItem));
     423       
     424  // Load history buffer from file if existing
     425  string Filename = New.HistService->getName();
     426  for (int j=0; j<Filename.size(); j++) if (Filename[j] == '/') Filename[j] = '_';
     427  FILE *File = fopen((HistDir + "/" + Filename).c_str(), "rb");
     428  if (File != NULL) {
     429    fread(&New.HistPointer, sizeof(New.HistPointer), 1, File);
     430    fread(New.HistBuffer, sizeof(EvidenceHistoryItem), HistSize, File);
     431    fclose(File);
     432  }
     433 
    405434  // Subscribe to service
    406   List[NumItems].DataItem = new DimStampedInfo(Name, NO_LINK, this);
    407 
    408   // Increase number only after all set-up
    409   NumItems++;
     435  New.DataItem = new DimStampedInfo(Name.c_str(), NO_LINK, this);
     436
     437  // Add item to list
     438  List.push_back(New);
    410439}
    411440
Note: See TracChangeset for help on using the changeset viewer.