// =====================================================================
//  $Id: TSystemLogging.cc,v 1.7 2004/06/24 15:15:26 goiwai Exp $
//  $Name: CLDAQ-1-14-06 $
//  $Log: TSystemLogging.cc,v $
//  Revision 1.7  2004/06/24 15:15:26  goiwai
//  たくさんの変更
//  Tcout,Tcerr,Tlogをバッファ経由にした。
//  何個かexternした。Tlog,Tcout,Tcerr,Tinfo...Tcritなど出力関係。
//
//  Revision 1.6  2004/03/07 10:30:34  goiwai
//  ROOTに組みこむためのおまじないマクロを埋めこみました。
//  全てにおいて完全に動作するわけではありません。
//
//  Revision 1.5  2003/12/06 10:13:51  goiwai
//  TSystemLogging& operator=() -> const TSystemLogging& operator=()
//  に変更しました.
//
//  Revision 1.4  2003/12/04 23:19:52  goiwai
//  システムロガーにメッセージ送信するための部品です.
//  ここでexternするとリンクできないといって怒られるので
//  Tsyslog.hというファイルでextern宣言しています.
//
//  Revision 1.3  2003/10/06 16:38:26  goiwai
//  *** empty log message ***
//
//  Revision 1.2  2003/07/30 16:21:21  goiwai
//  ファイルにコミットログをつけることにしました.
//
// =====================================================================
#include "TSystemLogging.hh"

TSystemLogging::TSystemLogging( Tint level, Tint facility, Tint option )
  : theLevel( level ), 
    theFacility( facility ), 
    theOption( option ),
    theID(),
    theMessageBuffer()
{
  SetID();
}

TSystemLogging::TSystemLogging( const TSystemLogging& right )
  : theLevel( right.theLevel ), 
    theFacility( right.theFacility ), 
    theOption( right.theOption ),
    theID(),
    theMessageBuffer( right.theMessageBuffer )
{
  SetID();
}

TSystemLogging::~TSystemLogging()
{
  Close();
}

Tvoid TSystemLogging::Open( Tint option, Tint facility )
{
  SetOption( option );
  SetFacility( facility );
  Open();
  return;
}

Tvoid TSystemLogging::Open( Tint option )
{
  SetOption( option );
  Open();
  return;
}

Tvoid TSystemLogging::Open()
{
  openlog( theID.c_str(), theOption, theFacility );
  return;
}

Tvoid TSystemLogging::Close()
{
  closelog();
  return;
}

Tvoid TSystemLogging::Record( Tint level, const Tstring& format, ... )
{
  va_list ap;
  va_start( ap,&format );
  va_end(ap);
  Record( level, format, ap );
  return;
}

Tvoid TSystemLogging::Record( const Tstring& format, ...)
{
  va_list ap;
  va_start(ap,&format);
  va_end(ap);
  Record(format,ap);
  return;
}

Tvoid TSystemLogging::Record( Tint level, const Tstring& format, va_list ap )
{
  SetLevel(level);
  Record(format,ap);
  return;
}

Tvoid TSystemLogging::Record( const Tstring& format, va_list ap )
{
  Open();
  vsyslog(theLevel|theFacility,format.c_str(),ap);
  Close();
  return;
}

Tvoid TSystemLogging::SetID()
{
  static const Tstring _EMERG_ID = "CLDAQ:EMERG";
  static const Tstring _ALERT_ID = "CLDAQ:ALERT";
  static const Tstring _CRIT_ID = "CLDAQ:CRIT";
  static const Tstring _ERROR_ID = "CLDAQ:ERROR";
  static const Tstring _WARNING_ID = "CLDAQ:WARNING";
  static const Tstring _NOTICE_ID = "CLDAQ:NOTICE";
  static const Tstring _INFO_ID = "CLDAQ:INFO";
  static const Tstring _DEBUG_ID = "CLDAQ:DEBUG";
 
  switch ( theLevel ) {
    case EMERG:
      theID = _EMERG_ID;
      break;
    case ALERT:
      theID = _ALERT_ID;
      break;
    case CRIT:
      theID = _CRIT_ID;
      break;
    case ERROR:
      theID = _ERROR_ID;
      break;
    case WARNING:
      theID = _WARNING_ID;
      break;
    case NOTICE:
      theID = _NOTICE_ID;
      break;
    case INFO:
      theID = _INFO_ID;
      break;
    case DEBUG:
      theID = _DEBUG_ID;
      break;
    default:
      theID = _INFO_ID;
      break;
  }
  return;
}

const TSystemLogging& TSystemLogging::operator=( const TSystemLogging& right )
{
  theLevel = right.theLevel;
  theFacility = right.theFacility;
  theOption = right.theOption;
  SetID();
  theMessageBuffer = right.theMessageBuffer;
  return *this;
}

TSystemLogging& TSystemLogging::operator<<( Tint* n )
{
  static const Tint buflen = 16;
  static Tchar buf[ buflen ];
  Tostrstream os( buf, buflen );
  os << n << Tflush;
  Tstring s = os.str();
  return *this << s;
}

TSystemLogging& TSystemLogging::operator<<( Tostream& (*pf)(Tostream&) )
{
  Record( theMessageBuffer );
  switch ( theLevel ) {
    case EMERG:
    case ALERT:
      Tcerr << theMessageBuffer << pf;
      exit( EXIT_FAILURE );
      break;
    case CRIT:
      Tcerr << theMessageBuffer << pf;
      exit( EXIT_SUCCESS );
      break;
    case ERROR:
      Tcerr << theMessageBuffer << pf;
      break;
    case WARNING:
    case NOTICE:
    case INFO:
    case DEBUG:
    default:
      Tcout << theMessageBuffer << pf;
      break;
  }
  ClearBuffer();
  return *this;
}

TSystemLogging Temerg( TSystemLogging::EMERG );
TSystemLogging Talert( TSystemLogging::ALERT );
TSystemLogging Tcrit( TSystemLogging::CRIT );
TSystemLogging Terror( TSystemLogging::ERROR );
TSystemLogging Twarn( TSystemLogging::WARNING );
TSystemLogging Tnotice( TSystemLogging::NOTICE );
TSystemLogging Tinfo( TSystemLogging::INFO );
TSystemLogging Tdebug( TSystemLogging::DEBUG );

#ifdef __CLDAQ_ROOT_DLL
    ClassImp(TSystemLogging)
#endif
