XRootD
XrdSsiLogger.cc
Go to the documentation of this file.
1 /******************************************************************************/
2 /* */
3 /* X r d S s i L o g g e r . c c */
4 /* */
5 /* (c) 2013 by the Board of Trustees of the Leland Stanford, Jr., University */
6 /* Produced by Andrew Hanushevsky for Stanford University under contract */
7 /* DE-AC02-76-SFO0515 with the Deprtment of Energy */
8 /* */
9 /* This file is part of the XRootD software suite. */
10 /* */
11 /* XRootD is free software: you can redistribute it and/or modify it under */
12 /* the terms of the GNU Lesser General Public License as published by the */
13 /* Free Software Foundation, either version 3 of the License, or (at your */
14 /* option) any later version. */
15 /* */
16 /* XRootD is distributed in the hope that it will be useful, but WITHOUT */
17 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
18 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
19 /* License for more details. */
20 /* */
21 /* You should have received a copy of the GNU Lesser General Public License */
22 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
23 /* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
24 /* */
25 /* The copyright holder's institutional names and contributor's names may not */
26 /* be used to endorse or promote products derived from this software without */
27 /* specific prior written permission of the institution or contributor. */
28 /******************************************************************************/
29 
30 #include <fcntl.h>
31 #include <cstdio>
32 #include <cstdarg>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <sys/time.h>
36 
37 #include "XrdVersion.hh"
38 #include "XrdCl/XrdClDefaultEnv.hh"
39 #include "XrdCl/XrdClLog.hh"
40 #include "XrdOuc/XrdOucEnv.hh"
41 #include "XrdOuc/XrdOucStream.hh"
43 #include "XrdSsi/XrdSsiLogger.hh"
44 #include "XrdSys/XrdSysError.hh"
45 #include "XrdSys/XrdSysHeaders.hh"
46 #include "XrdSys/XrdSysLogger.hh"
47 #include "XrdSys/XrdSysPthread.hh"
48 #include "XrdSys/XrdSysTrace.hh"
49 
50 /******************************************************************************/
51 /* G l o b a l O b j e c t s */
52 /******************************************************************************/
53 
54 namespace XrdSsi
55 {
56  XrdSysError Log(0, "ssi_");
61 }
62 
63 using namespace XrdSsi;
64 
65 /******************************************************************************/
66 /* C l i e n t L o g g i n g I n t e r c e p t */
67 /******************************************************************************/
68 
69 namespace
70 {
71 class LogMCB : public XrdCl::LogOut
72 {
73 public:
74 
75 virtual void Write(const std::string &msg);
76 
77  LogMCB(XrdSsiLogger::MCB_t *pMCB) : mcbP(pMCB) {}
78 virtual ~LogMCB() {}
79 
80 private:
82 };
83 
84 void LogMCB::Write(const std::string &msg)
85 {
86  timeval tNow;
87  const char *brak, *cBeg, *cMsg = msg.c_str();
88  unsigned long tID = XrdSysThread::Num();
89  int cLen = msg.size();
90 
91 // Get the actual time right now
92 //
93  gettimeofday(&tNow, 0);
94 
95 // Client format: [tod][loglvl][topic] and [pid] may follow
96 //
97  cBeg = cMsg;
98  for (int i = 0; i < 4; i++)
99  {if (*cMsg != '[' || !(brak = index(cMsg, ']'))) break;
100  cMsg = brak+1;
101  }
102 
103 // Skip leading spaces now
104 //
105  while(*cMsg == ' ') cMsg++;
106 
107 // Recalculate string length
108 //
109  cLen = cLen - (cMsg - cBeg);
110  if (cLen < 0) cLen = strlen(cMsg);
111  mcbP(tNow, tID, cMsg, cLen);
112 }
113 }
114 
115 /******************************************************************************/
116 /* M s g */
117 /******************************************************************************/
118 
119 void XrdSsiLogger::Msg(const char *pfx, const char *txt1,
120  const char *txt2, const char *txt3)
121 {
122 
123 // Route the message appropriately
124 //
125  if (pfx) Log.Emsg(pfx, txt1, txt2, txt3);
126  else {const char *tout[6] = {txt1, 0};
127  int i = 1;
128  if (txt2) {tout[i++] = " "; tout[i++] = txt2;}
129  if (txt3) {tout[i++] = " "; tout[i++] = txt3;}
130  tout[i] = txt3;
131  Log.Say(tout[0], tout[1], tout[2], tout[3], tout[4], tout[5]);
132  }
133 }
134 
135 /******************************************************************************/
136 /* M s g f */
137 /******************************************************************************/
138 
139 void XrdSsiLogger::Msgf(const char *pfx, const char *fmt, ...)
140 {
141  char buffer[2048];
142  va_list args;
143  va_start (args, fmt);
144 
145 // Format the message
146 //
147  vsnprintf(buffer, sizeof(buffer), fmt, args);
148 
149 // Route it
150 //
151  if (pfx) Log.Emsg(pfx, buffer);
152  else Log.Say(buffer);
153 }
154 
155 /******************************************************************************/
156 /* M s g v */
157 /******************************************************************************/
158 
159 void XrdSsiLogger::Msgv(const char *pfx, const char *fmt, va_list aP)
160 {
161  char buffer[2048];
162 
163 // Format the message
164 //
165  vsnprintf(buffer, sizeof(buffer), fmt, aP);
166 
167 // Route it
168 //
169  if (pfx) Log.Emsg(pfx, buffer);
170  else Log.Say(buffer);
171 }
172 
173 /******************************************************************************/
174 
175 void XrdSsiLogger::Msgv(struct iovec *iovP, int iovN)
176 {
177  Logger->Put(iovN, iovP);
178 }
179 
180 /******************************************************************************/
181 /* S e t M C B */
182 /******************************************************************************/
183 
186 {
187 // Record the callback, this may be on the server or the client
188 //
189  if (mcbt == mcbAll || mcbt == mcbServer) msgCB = mcbP;
190 
191 // If setting the clientside, get the client logging object and set a new
192 // logging intercept object that will route the messages here.
193 //
194  if (mcbt == mcbAll || mcbt == mcbClient)
196  if (!logP) return false;
197  logP->SetOutput(new LogMCB(&mcbP));
198  msgCBCl = mcbP;
199  }
200 
201 // All done
202 //
203  return true;
204 }
205 
206 /******************************************************************************/
207 /* T B e g */
208 /******************************************************************************/
209 
210 const char *XrdSsiLogger::TBeg() {return Logger->traceBeg();}
211 
212 /******************************************************************************/
213 /* T E n d */
214 /******************************************************************************/
215 
217 {
218  std::cerr <<std::endl;
219  Logger->traceEnd();
220 }
static Log * GetLog()
Get default log.
Interface for logger outputs.
Definition: XrdClLog.hh:49
Handle diagnostics.
Definition: XrdClLog.hh:101
void SetOutput(LogOut *output)
Set the output that should be used.
Definition: XrdClLog.hh:215
void() MCB_t(struct timeval const &mtime, unsigned long tID, const char *msg, int mlen)
Length of message text.
static bool SetMCB(MCB_t &mcbP, mcbType mcbt=mcbAll)
static void Msgf(const char *pfx, const char *fmt,...)
static void Msg(const char *pfx, const char *txt1, const char *txt2=0, const char *txt3=0)
static const char * TBeg()
static void Msgv(const char *pfx, const char *fmt, va_list aP)
static void TEnd()
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
Definition: XrdSysError.cc:95
void Say(const char *text1, const char *text2=0, const char *txt3=0, const char *text4=0, const char *text5=0, const char *txt6=0)
Definition: XrdSysError.cc:141
void Put(int iovcnt, struct iovec *iov)
char * traceBeg()
static unsigned long Num(void)
XrdSsiLogger::MCB_t * msgCB
Definition: XrdSsiLogger.cc:59
XrdSsiLogger::MCB_t * msgCBCl
Definition: XrdSsiLogger.cc:60
XrdSysTrace Trace
Definition: XrdSsiSfs.cc:107
XrdSysLogger * Logger
Definition: XrdSsiLogger.cc:57
XrdSysError Log