Commit be3117b3 authored by Claes Sjofors's avatar Claes Sjofors

Xtt: logging of operator actions

parent 3277b757
......@@ -90,6 +90,9 @@
#define STS_K_SEVERE 4 /**< SEVERE ERROR */
static void (*gdh_log_cb)(char *, void *, unsigned int) = 0;
/**
* @brief This routine fetches the minimum, not visible alarmlevel for a
* certain object.
......@@ -2538,6 +2541,8 @@ gdh_SetObjectInfo (
cvolc_SetObjectInfo(&sts, np, arp, ccp, rarp, ridx, ap, bufp, bufsize);
}
if ( gdh_log_cb && ODD(sts))
gdh_log_cb( name, bufp, bufsize);
if (ccpLocked) {
gdb_Lock;
......@@ -4937,3 +4942,7 @@ pwr_tStatus gdh_GetSecurityInfo(
return gdh_GetObjectInfoAttrref( &aref, security, sizeof(*security));
}
void gdh_RegisterLogFunction( void (*func)(char *, void *, unsigned int))
{
gdh_log_cb = func;
}
......@@ -792,6 +792,11 @@ gdh_SetCache (
pwr_tUInt32 trimmed_level
);
void
gdh_RegisterLogFunction(
void (*func)(char *, void *, unsigned int)
);
/** @} */
#if defined __cplusplus
......
/*
* Proview $Id$
* Copyright (C) 2005 SSAB Oxelsund AB.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with the program, if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
**/
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <iomanip>
#include <string.h>
#include "pwr.h"
#include "co_time.h"
#include "cow_log.h"
#include "co_time.h"
#include "cow_wow.h"
#include "xtt_log.h"
#include "xtt_xnav.h"
#include "rt_gdh.h"
using namespace std;
XttLog *XttLog::m_default_log = 0;
XttLog::XttLog( const char *filename) : m_level(1)
{
char category_str[20];
dcli_translate_filename( m_filename, filename);
strncpy(m_pid,syi_ProcessId(),sizeof(m_pid));
gdh_RegisterLogFunction( gdh_log_bc);
category_to_string(xttlog_eCategory_LogStart, category_str);
log( category_str, 0, 0, 0);
}
void XttLog::delete_default()
{
if ( m_default_log) {
delete m_default_log;
m_default_log = 0;
}
}
void XttLog::gdh_log_bc( char *name, void *value, unsigned int size)
{
char str[1000];
unsigned int strsize = sizeof(str);
unsigned int len = 0;
for ( unsigned int i = 0; i < size; i++) {
if ( i == size - 1) {
if ( len + 4 >= strsize)
break;
len += sprintf( &str[i*5], "0x%02hhx", *(((unsigned char *)value)+i));
}
else {
if ( len + 5 >= strsize)
break;
len += sprintf( &str[i*5], "0x%02hhx,", *(((unsigned char *)value)+i));
}
}
dlog( xttlog_eCategory_SetObjectInfo, name, str, 0);
}
void XttLog::dlog( xttlog_eCategory category, const char *str, const char *value, unsigned int opt)
{
char category_str[40];
category_to_string(category, category_str);
if ( m_default_log)
m_default_log->log( category_str, str, value, opt);
}
void XttLog::category_to_string( xttlog_eCategory category, char *str)
{
switch ( category) {
case xttlog_eCategory_OpenGraph:
strcpy( str, "OpenGraph");
break;
case xttlog_eCategory_CloseGraph:
strcpy( str, "CloseGraph");
break;
case xttlog_eCategory_SetObjectInfo:
strcpy( str, "SetObjectInfo");
break;
case xttlog_eCategory_Command:
strcpy( str, "Command");
break;
case xttlog_eCategory_ApplNew:
strcpy( str, "ApplNew");
break;
case xttlog_eCategory_ApplDelete:
strcpy( str, "ApplDelete");
break;
case xttlog_eCategory_LogStart:
strcpy( str, "LogStart");
break;
default:
strcpy( str, "");
}
}
void XttLog::string_to_category( char *str, xttlog_eCategory *category)
{
if ( strcmp( str, "OpenGraph") == 0)
*category = xttlog_eCategory_OpenGraph;
else if ( strcmp( str, "CloseGraph") == 0)
*category = xttlog_eCategory_CloseGraph;
else if ( strcmp( str, "SetObjectInfo") == 0)
*category = xttlog_eCategory_SetObjectInfo;
else if ( strcmp( str, "Command") == 0)
*category = xttlog_eCategory_Command;
else if ( strcmp( str, "ApplNew") == 0)
*category = xttlog_eCategory_ApplNew;
else if ( strcmp( str, "ApplDelete") == 0)
*category = xttlog_eCategory_ApplDelete;
else if ( strcmp( str, "LogStart") == 0)
*category = xttlog_eCategory_LogStart;
else
*category = xttlog_eCategory_;
}
void XttLog::log( const char *category, const char *str, const char *value,
unsigned int opt)
{
ofstream fp;
pwr_tStatus sts;
char timstr[40];
char username[80];
time_AtoAscii( 0, time_eFormat_DateAndTime, timstr, sizeof(timstr));
sts = syi_UserName( username, sizeof(username));
if ( EVEN(sts))
strcpy( username, "Unknown");
for ( int i = 0; i < 5; i++) {
fp.open( m_filename, ios::out | ios::app);
if ( fp)
break;
sleep(1);
}
if ( !fp)
return;
if ( m_level == 1)
fp << "1 ";
else
fp << " " << m_level << " ";
fp << timstr << " " << m_pid;
for ( int i = strlen(m_pid); i < 7; i++)
fp << " ";
fp << " " << category;
for ( int i = strlen(category); i < 11; i++)
fp << " ";
fp << " ";
fp << " " << username;
for ( int i = strlen(username); i < 11; i++)
fp << " ";
fp << " ";
if ( str)
fp << str;
if ( value)
fp << " \"" << value << "\"";
fp << endl;
fp.close();
}
int XttLog::play( XNav *xnav, char *filename, double speed, int pid)
{
ifstream fp;
pwr_tFileName fname;
char line[1000];
int ind;
int lpid;
char t1[20], t2[20];
char type[40];
char user[40];
char attr[512];
char value[1000];
xttlog_eCategory category;
int num;
char timstr[40];
pwr_tTime log_time;
pwr_tTime prev_time;
pwr_tDeltaTime diff_time;
float diff_time_f;
int first = 1;
if ( speed < 0.01)
speed = 1;
dcli_translate_filename( fname, filename);
fp.open( fname);
if ( !fp)
return 0;
while( fp.getline( line, sizeof(line))) {
num = sscanf( line, "%d %s %s %d %s %s", &ind, t1, t2, &lpid, type, user);
if ( pid != 0 && pid != lpid)
continue;
strcpy( timstr, t1);
strcat( timstr, " ");
strcat( timstr, t2);
time_AsciiToA( timstr, &log_time);
if ( !first) {
time_Adiff( &diff_time, &log_time, &prev_time);
diff_time_f = time_DToFloat( 0, &diff_time);
}
else
diff_time_f = 0;
if ( diff_time_f / speed > 0.01) {
xnav->wow->Wait( diff_time_f / speed);
}
char *s;
int cnt = 0;
for ( s = line; *s; s++) {
if ( s > line &&
( *(s-1) == ' ' || *(s-1) == ' ') &&
( *s != ' ' && *s != ' '))
cnt++;
if ( cnt == num)
break;
}
string_to_category( type, &category);
switch ( category) {
case xttlog_eCategory_Command:
case xttlog_eCategory_OpenGraph:
case xttlog_eCategory_CloseGraph:
case xttlog_eCategory_ApplNew:
case xttlog_eCategory_ApplDelete: {
int sts = xnav->command( s);
printf( "%8.3f %-14s %9d %s\n", diff_time_f, type, sts, s);
break;
}
case xttlog_eCategory_SetObjectInfo: {
unsigned int len;
unsigned char buf[500];
int size;
pwr_tStatus sts;
sscanf( s, "%s %s", attr, value);
unsigned int i = 0;
while (1) {
len = sscanf( &value[i*5+1], "0x%2hhx", &buf[i]);
if ( len != 1)
break;
i++;
if ( value[i*5] != ',' || i >= sizeof(buf))
break;
}
size = i;
if ( size) {
sts = gdh_SetObjectInfo( attr, buf, size);
if ( EVEN(sts)) {
printf( "gdh_SetObjectInfo error: %s %s\n", attr, value);
}
}
printf( "%8.3f %-14s %9d %s %s\n", diff_time_f, type, sts, attr, value);
break;
}
case xttlog_eCategory_LogStart:
printf( "%8.3f %-14s\n", diff_time_f, type);
break;
default: ;
}
prev_time = log_time;
if ( first)
first = 0;
}
printf( " %-14s\n", "EndOfFile");
return 1;
}
/*
* Proview $Id$
* Copyright (C) 2005 SSAB Oxelsund AB.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with the program, if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
**/
#ifndef xtt_log_h
#define xtt_log_h
#include "pwr.h"
#include "cow_log.h"
#define xttlog_cLogFile "$pwrp_log/xtt.log"
typedef enum {
xttlog_eCategory_,
xttlog_eCategory_Command,
xttlog_eCategory_OpenGraph,
xttlog_eCategory_CloseGraph,
xttlog_eCategory_ApplNew,
xttlog_eCategory_ApplDelete,
xttlog_eCategory_SetObjectInfo,
xttlog_eCategory_LogStart,
xttlog_eCategory__,
} xttlog_eCategory;
class XttLog;
class XNav;
class XttLog
{
pwr_tFileName m_filename;
int m_level;
char m_pid[40];
static XttLog *m_default_log;
public:
void push() { m_level++;}
void pull() {
m_level--;
if ( m_level < 1)
m_level = 1;
}
XttLog( const char *filename);
~XttLog() { if ( this == m_default_log) m_default_log = 0;}
void set_default() { m_default_log = this;}
void log( const char *category, const char *str, const char *value,
unsigned int opt);
static void dlog( xttlog_eCategory category, const char *str, const char *value, unsigned int opt = 0);
static void category_to_string( xttlog_eCategory category, char *str);
static void string_to_category( char *str, xttlog_eCategory *category);
static void dpush() {
if ( m_default_log) m_default_log->push();}
static void dpull() {
if ( m_default_log) m_default_log->pull();}
static void gdh_log_bc( char *name, void *buf, unsigned int bufsize);
static int play( XNav *xnav, char *filename, double speed, int pid);
static void delete_default();
};
#endif
......@@ -56,6 +56,7 @@
#include "xtt_op.h"
#include "xtt_audio.h"
#include "xtt_trace.h"
#include "xtt_log.h"
#define max(Dragon,Eagle) ((Dragon) > (Eagle) ? (Dragon) : (Eagle))
#define min(Dragon,Eagle) ((Dragon) < (Eagle) ? (Dragon) : (Eagle))
......@@ -3545,6 +3546,92 @@ ApplListElem::ApplListElem( applist_eType al_type, void *al_ctx,
strcpy( instance, al_instance);
else
strcpy( instance, "");
log_new();
}
void ApplListElem::log_new()
{
switch( type) {
case applist_eType_Graph: {
pwr_tCmd cmd;
if ( strcmp( instance, "") == 0)
sprintf( cmd, "open graph \"%s\"", name);
else
sprintf( cmd, "open graph \"%s\"/inst=%s", name, instance);
XttLog::dlog( xttlog_eCategory_ApplNew, cmd, 0, 0);
break;
}
case applist_eType_Trend: {
pwr_tCmd cmd;
pwr_tStatus sts;
pwr_tAName aname;
sts = gdh_AttrrefToName( &aref, aname, sizeof(aname), cdh_mName_volumeStrict);
if ( EVEN(sts)) return;
snprintf( cmd, sizeof(cmd), "open trend %s", aname);
XttLog::dlog( xttlog_eCategory_ApplNew, cmd, 0, 0);
break;
}
case applist_eType_Trace: {
pwr_tCmd cmd;
pwr_tStatus sts;
pwr_tAName aname;
sts = gdh_AttrrefToName( &aref, aname, sizeof(aname), cdh_mName_volumeStrict);
if ( EVEN(sts)) return;
snprintf( cmd, sizeof(cmd), "open trace %s", aname);
XttLog::dlog( xttlog_eCategory_ApplNew, cmd, 0, 0);
break;
}
case applist_eType_Attr:
break;
default: ;
}
}
void ApplListElem::log_delete()
{
switch( type) {
case applist_eType_Graph: {
pwr_tCmd cmd;
if ( strcmp( instance, "") == 0)
sprintf( cmd, "close graph \"%s\"", name);
else
sprintf( cmd, "close graph \"%s\"/inst=%s", name, instance);
XttLog::dlog( xttlog_eCategory_ApplDelete, cmd, 0, 0);
break;
}
case applist_eType_Trend: {
pwr_tCmd cmd;
pwr_tStatus sts;
pwr_tAName aname;
sts = gdh_AttrrefToName( &aref, aname, sizeof(aname), cdh_mName_volumeStrict);
if ( EVEN(sts)) return;
snprintf( cmd, sizeof(cmd), "close trend %s", aname);
XttLog::dlog( xttlog_eCategory_ApplDelete, cmd, 0, 0);
break;
}
case applist_eType_Trace: {
pwr_tCmd cmd;
pwr_tStatus sts;
pwr_tAName aname;
sts = gdh_AttrrefToName( &aref, aname, sizeof(aname), cdh_mName_volumeStrict);
if ( EVEN(sts)) return;
snprintf( cmd, sizeof(cmd), "close trace %s", aname);
XttLog::dlog( xttlog_eCategory_ApplDelete, cmd, 0, 0);
break;
}
case applist_eType_Attr:
break;
default: ;
}
}
void ApplList::insert( applist_eType type, void *ctx,
......@@ -3576,6 +3663,7 @@ void ApplList::remove( void *ctx)
root = elem->next;
else
prev->next = elem->next;
delete elem;
return;
}
......
......@@ -190,12 +190,16 @@ class ApplListElem {
public:
ApplListElem( applist_eType al_type, void *al_ctx, pwr_sAttrRef *al_arp,
const char *al_name, const char *al_instance);
~ApplListElem() { log_delete();}
applist_eType type;
void *ctx;
pwr_sAttrRef aref;
char name[80];
pwr_tAName instance;
ApplListElem *next;
void log_new();
void log_delete();
};
class ApplList {
......
......@@ -76,6 +76,7 @@
#include "xtt_clog.h"
#include "xtt_hist.h"
#include "xtt_fileview.h"
#include "xtt_log.h"
class xnav_file {
public:
......@@ -213,6 +214,8 @@ static int xnav_read_func( void *client_data,
void *client_flag);
static int xnav_wait_func( void *client_data,
void *client_flag);
static int xnav_oplog_func( void *client_data,
void *client_flag);
dcli_tCmdTable xnav_command_table[] = {
{
......@@ -381,6 +384,11 @@ dcli_tCmdTable xnav_command_table[] = {
&xnav_wait_func,
{ "dcli_arg1", "/TIME", ""}
},
{
"OPLOG",
&xnav_oplog_func,
{ "dcli_arg1", "/FILE", "/SPEED", "/PID", ""}
},
{"",}};
......@@ -2998,12 +3006,32 @@ static int xnav_open_func( void *client_data,
}
}
}
else {
if ( names == 1) {
if ( xnav->appl.find( applist_eType_Trend, &aref_vect[0], (void **) &trend)) {
trend->pop();
}
else {
trend = xnav->xtttrend_new( title_str, aref_vect, 0, &sts);
if ( ODD(sts))
if ( EVEN(sts))
xnav->message('E',"Error in trend configuration");
else {
trend->close_cb = xnav_trend_close_cb;
trend->help_cb = xnav_trend_help_cb;
xnav->appl.insert( applist_eType_Trend, (void *)trend, &aref_vect[0], "",
NULL);
}
}
}
else {
trend = xnav->xtttrend_new( title_str, aref_vect, 0, &sts);
if ( ODD(sts)) {
trend->help_cb = xnav_trend_help_cb;
trend->help_cb = xnav_trend_help_cb;
}
}
}
}
else if ( cdh_NoCaseStrncmp( arg1_str, "SHISTORY", strlen( arg1_str)) == 0)
{
pwr_tAName name_str;
......@@ -3643,7 +3671,7 @@ static int xnav_close_func( void *client_data,
pwr_tAName name_str;
char *name_ptr;
pwr_tObjid objid;
pwr_tAttrRef aref;
int sts;
int plotgroup_found = 0;
pwr_tClassId classid;
......@@ -3689,16 +3717,17 @@ static int xnav_close_func( void *client_data,
else
strcpy( trend_name, name_str);
sts = gdh_NameToObjid( trend_name, &objid);
sts = gdh_NameToAttrref( pwr_cNObjid, trend_name, &aref);
if (EVEN(sts)) {
xnav->message('E', "Object not found");
return XNAV__HOLDCOMMAND;
}
sts = gdh_GetObjectClass( objid, &classid);
sts = gdh_GetAttrRefTid( &aref, &classid);
if (EVEN(sts)) return sts;
switch ( classid) {
case pwr_cClass_PlotGroup:
case pwr_cClass_DsTrend:
plotgroup_found = 1;
break;
default:
......@@ -3707,7 +3736,7 @@ static int xnav_close_func( void *client_data,
}
if ( plotgroup_found) {
if ( xnav->appl.find( applist_eType_Trend, objid, (void **) &trend)) {
if ( xnav->appl.find( applist_eType_Trend, &aref, (void **) &trend)) {
xnav->appl.remove( (void *)trend);
delete trend;
}
......@@ -5360,6 +5389,78 @@ static int xnav_wait_func(void *client_data,
return XNAV__SUCCESS;
}
static int xnav_oplog_func(void *client_data,
void *client_flag)
{
XNav *xnav = (XNav *)client_data;
char arg1_str[80];
int arg1_sts;
arg1_sts = dcli_get_qualifier( "dcli_arg1", arg1_str, sizeof(arg1_str));
if ( cdh_NoCaseStrncmp( arg1_str, "START", strlen( arg1_str)) == 0) {
pwr_tFileName file_str;
if ( EVEN( dcli_get_qualifier( "/FILE", file_str, sizeof(file_str)))) {
strcpy( file_str, xttlog_cLogFile);
}
XttLog *log = new XttLog( file_str);
XttLog::delete_default();
log->set_default();
xnav->message('I', "Operator logging started");
}
else if ( cdh_NoCaseStrncmp( arg1_str, "STOP", strlen( arg1_str)) == 0) {
XttLog::delete_default();
xnav->message('I', "Operator logging stopped");
}
else if ( cdh_NoCaseStrncmp( arg1_str, "PLAY", strlen( arg1_str)) == 0) {
pwr_tStatus sts;
pwr_tFileName file_str;
int num;
char speed_str[40];
double speed;
char pid_str[40];
int pid;
if ( EVEN( dcli_get_qualifier( "/FILE", file_str, sizeof(file_str)))) {
strcpy( file_str, xttlog_cLogFile);
}
if ( ODD( dcli_get_qualifier( "/SPEED", speed_str, sizeof(speed_str)))) {
num = sscanf( speed_str, "%lf", &speed);
if ( num != 1) {
xnav->message('E', "Speed syntax error");
return XNAV__HOLDCOMMAND;
}
}
else
speed = 1;
if ( ODD( dcli_get_qualifier( "/PID", pid_str, sizeof(pid_str)))) {
num = sscanf( pid_str, "%d", &pid);
if ( num != 1) {
xnav->message('E', "Pid syntax error");
return XNAV__HOLDCOMMAND;
}
}
else
pid = 0;
sts = XttLog::play( xnav, file_str, speed, pid);
if ( EVEN(sts))
xnav->message(' ', XNav::get_message(sts));
}
else {
xnav->message('E',"Syntax error");
return XNAV__HOLDCOMMAND;
}
return XNAV__SUCCESS;
}
int XNav::show_database()
{
int sts;
......@@ -5436,6 +5537,8 @@ int XNav::command( char* input_str)
sts = dcli_replace_symbol( input_str, command, sizeof(command));
if ( EVEN(sts)) return sts;
XttLog::dlog( xttlog_eCategory_Command, command, 0, 0);
sts = dcli_cli( (dcli_tCmdTable *)&xnav_command_table, command, (void *) this, 0);
if ( sts == DCLI__COM_NODEF)
{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment