Changeset 152


Ignore:
Timestamp:
Jan 27, 2010, 3:28:06 PM (11 years ago)
Author:
ogrimm
Message:
Updates
Location:
Evidence
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • Evidence/Alarm.cc

    r145 r152  
    5151  AlarmSummary = new char [SUMMARYSIZE];
    5252  MasterAlarm = 0;
    53  
     53
    5454  char *ServerNames = GetConfig(SERVER_NAME " servers");
    5555
  • 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
  • Evidence/Edd/Edd.cc

    r151 r152  
    174174  Grid->attach(this);
    175175  Legend = new QwtLegend();
     176  Legend->setItemMode(QwtLegend::ClickableItem);
    176177  insertLegend(Legend, QwtPlot::TopLegend);
    177178
     179  connect(this, SIGNAL(legendClicked (QwtPlotItem *)), SLOT(LegendClicked(QwtPlotItem *)));
     180 
    178181  // Connect to DIM handler
    179182  if (connect(Handler, SIGNAL(YEP(DimInfo *, int, QString, QByteArray, QString)), SLOT(Update(DimInfo *, int, QString, QByteArray, QString))) == false) {
     
    409412}
    410413   
    411 //
    412414// Opening context menu
    413 //
    414415void Edd_Plot::contextMenuEvent(QContextMenuEvent *Event) {
    415416
     
    417418}
    418419
     420// Drag&Drop method
     421void Edd_Plot::LegendClicked(QwtPlotItem *Item) {
     422
     423  QDrag *Drag = new QDrag(this);
     424  QMimeData *MimeData = new QMimeData;
     425  MimeData->setText(Item->title().text().remove(".hist"));
     426  Drag->setMimeData(MimeData);
     427  Drag->exec();
     428}
     429
     430
     431// Zoom completely out
    419432void Edd_Plot::MenuZoomOut() {
    420433
     
    648661  Graph = new Edd_Plot();
    649662  for (int i=0; i<18; i++) {
    650     Text = Text.sprintf("BIAS/VOLT/ID00/00-%.3d",i);
     663    Text = Text.sprintf("Bias/VOLT/ID00/00-%.3d",i);
    651664    Value = new Edd_Indicator(Text);
    652665    BiasLayout->addWidget(Value, i%9+1, 0+i/9, 1, 1);
    653666    Graph->AddService(Text);
    654667
    655     Text = Text.sprintf("BIAS/VOLT/ID00/01-%.3d",i);
     668    Text = Text.sprintf("Bias/VOLT/ID00/01-%.3d",i);
    656669    Value = new Edd_Indicator(Text);
    657670    BiasLayout->addWidget(Value, i%9+1, 2+i/9, 1, 1);
     
    660673
    661674  BiasLayout->addWidget(Graph, 0, 4, 12, 3);
    662   Value = new Edd_Indicator("BIAS/Status");
     675  Value = new Edd_Indicator("Bias/Status");
    663676  Value->setMaximumWidth(200);
    664677  BiasLayout->addWidget(Value, 0, 0, 1, 3);     
    665678
    666   Textout = new Edd_Textout("BIAS/Textout");
     679  Textout = new Edd_Textout("Bias/Textout");
    667680  Textout->setFixedWidth(400);
    668681  BiasLayout->addWidget(Textout, 10, 0, 4, 4);     
  • Evidence/Edd/Edd.h

    r142 r152  
    9696
    9797    void HandleZoom(const QwtDoubleRect &);
    98     void contextMenuEvent(QContextMenuEvent *);   
     98    void contextMenuEvent(QContextMenuEvent *);
     99        void LegendClicked(QwtPlotItem *);
    99100    void MenuZoomOut();
    100101    void MenuSingleTrace();       
  • Evidence/Evidence.cc

    r144 r152  
    2626
    2727bool EvidenceServer::ExitRequest = false;
     28string __StatusName;
    2829
    2930// Constructor starts server with given name
     
    3435  ConfigList = NULL;
    3536  ConfigNum = 0;
     37  __StatusName = string(Name) + "/Status";
    3638 
    3739  // Catch some signals
     
    4143  signal(SIGHUP, &SignalHandler);   // Terminal closed
    4244 
    43   // Create server name
    44   if (MakeString(&StatusName, "%s/Status", Name) == -1) {
    45     State(FATAL, "Could not generate service name, asprintf() failed");
    46   }
     45  // Catch C++ unhandled exceptions
     46  set_terminate(Terminate);
    4747 
    4848  // Start server
    49   Status = new DimService(StatusName, (char *) "Server started");
     49  Status = new DimService(__StatusName.c_str(), (char *) "Server started");
    5050
    5151  start(Name);
     
    5656EvidenceServer::~EvidenceServer() {
    5757
    58   free(StatusName);
    59  
    6058  for (unsigned int i=0; i<ConfigNum; i++) {
    6159        delete[] ConfigList[i].Name;
     
    9593  va_end(ArgumentPointer);
    9694
    97   snprintf(TBuf, sizeof(TBuf), "%s (%s): %s", StatusName, StateString[Severity], Tmp); // Normal string
     95  snprintf(TBuf, sizeof(TBuf), "%s (%s): %s", __StatusName.c_str(), StateString[Severity], Tmp); // Normal string
    9896  snprintf(SBuf, sizeof(SBuf), "%s*%c", Tmp, (char) Severity);
    9997  *(strrchr(SBuf, '*')) = '\0';  // String with severity encoding
     
    115113// The memory allocated by all calls to this function will be freed by
    116114// the destructor.
    117 char* EvidenceServer::GetConfig(const char *Item) {
     115char* EvidenceServer::GetConfig(const char *Item, const char *Default) {
    118116 
    119117  // Determine configuration file update time
     
    138136  DimRpcInfo Config((char *) "ConfigRequest", (char *) "");
    139137  Config.setData((char *) Item);
    140 
     138  char *Result = Config.getString();
     139 
    141140  // Terminate if not successful
    142   if (strlen(Config.getString()) == 0) {
    143     State(FATAL, "Missing configuration data '%s'", Item);
     141  if (strlen(Result) == 0) {
     142    if (Default == NULL) State(FATAL, "Missing configuration data '%s'", Item);
     143        Result = (char *) Default;
    144144  }
    145145
     
    157157 
    158158  // Allocate memory for strings, and copy data to this memory
    159   ConfigList[ItemNo].Value = new char [strlen(Config.getString())+1];
     159  ConfigList[ItemNo].Value = new char [strlen(Result)+1];
    160160  ConfigList[ItemNo].Name = new char [strlen(Item)+1];
    161161  strcpy(ConfigList[ItemNo].Name, Item);
    162   strcpy(ConfigList[ItemNo].Value, Config.getString());
     162  strcpy(ConfigList[ItemNo].Value, Result);
    163163
    164164  ConfigList[ItemNo].Time = Time;
     
    175175
    176176  EvidenceServer::ExitRequest = true;
     177}
     178
     179// C++ exception handler
     180void EvidenceServer::Terminate() {
     181
     182  string Msg = __StatusName + ": Caught unhandled exception";
     183  printf("%s\n", Msg.c_str());
     184  DimClient::sendCommand("DColl/Log", Msg.c_str());
     185 
     186  abort();
    177187}
    178188
     
    182192
    183193  char *Text;
     194  int R;
    184195 
    185196  if (strlen(Item->getFormat()) != 1) return NULL;
    186197 
    187198  switch (*(Item->getFormat())) {
    188     case 'I':  MakeString(&Text, "%d", Item->getInt());   break;
    189     case 'C':  MakeString(&Text, "%s", Item->getString());   break;
    190     case 'S':  MakeString(&Text, "%hd", Item->getShort());   break;
    191     case 'F':  MakeString(&Text, "%.5f", Item->getFloat());   break;
    192     case 'D':  MakeString(&Text, "%.5f", Item->getDouble());   break;
    193     case 'X':  MakeString(&Text, "%lld", Item->getLonglong());   break;
     199    case 'I':  R = asprintf(&Text, "%d", Item->getInt());   break;
     200    case 'C':  R = asprintf(&Text, "%s", Item->getString());   break;
     201    case 'S':  R = asprintf(&Text, "%hd", Item->getShort());   break;
     202    case 'F':  R = asprintf(&Text, "%.5f", Item->getFloat());   break;
     203    case 'D':  R = asprintf(&Text, "%.5f", Item->getDouble());   break;
     204    case 'X':  R = asprintf(&Text, "%lld", Item->getLonglong());   break;
    194205    default: return NULL;
    195206  }
    196207
    197   return Text;
    198 }
    199 
    200 //
    201 // Generate string with vasprintf()
    202 //
    203 // The pointer will be set to NULL in case of error, so can always safely passed to free().
    204 // In case vasprintf() is not available on a particular system, the functionality can
    205 // be manually implemented in this routine.
    206 //
    207 int EvidenceServer::MakeString(char **Pointer, const char *Format, ...) {
    208 
    209   int Ret;
    210   va_list ArgumentPointer; 
    211 
    212   va_start(ArgumentPointer, Format); 
    213   if ((Ret = vasprintf(Pointer, Format, ArgumentPointer)) == -1) Pointer = NULL;
    214   va_end(ArgumentPointer);
    215  
    216   return Ret;
    217 }
     208  return (R == -1) ? NULL : Text;
     209}
  • Evidence/Evidence.h

    r142 r152  
    44#include <stdio.h>
    55#include <stdarg.h>
     6#include <string>
    67#include <errno.h>
     8#include <exception>
    79
    810#include "dis.hxx"
     
    1113#define NO_LINK (char *) "__&DIM&NOLINK&__" // Data if no link available
    1214#define STATUS_SIZE 1000                                        // Bytes for status service string
     15
     16using namespace std;
    1317
    1418// Declaration of item for history buffer (see DColl.cc)
     
    2933        unsigned int ConfigNum;
    3034
    31     char *StatusName;
    3235    DimService *Status;
    3336
    34     static void SignalHandler(int);  // static needed for signal() function
     37    static void SignalHandler(int); // static for signal()
     38    static void Terminate();            // static for set_terminate()
    3539        void errorHandler(int, int, char *);
    3640        void exitHandler(int);
     
    4347
    4448        void State(StateType, const char *, ...);
     49        char* GetConfig(const char *, const char * = NULL);
     50        static char* ToString(DimInfo *);
    4551
    46         char* GetConfig(const char *);
    47         static char *ToString(DimInfo *);
    48         static int MakeString(char **Pointer, const char *Format, ...);
    49        
    5052    static bool ExitRequest;
    5153};
  • Evidence/Makefile

    r144 r152  
    2020        @rm -f $(PROG2) $(PROG2).o
    2121        @rm -f $(PROG3) $(PROG3).o
    22        
     22        @rm -f Evidence.o       
Note: See TracChangeset for help on using the changeset viewer.