00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "XrdMon/XrdMonDecArgParser.hh"
00014 #include "XrdMon/XrdMonDecDictInfo.hh"
00015 #include "XrdMon/XrdMonDecUserInfo.hh"
00016 #include "XrdMon/XrdMonHeader.hh"
00017 #include "XrdSys/XrdSysHeaders.hh"
00018 #include "XrdSys/XrdSysPlatform.hh"
00019 #include "XrdXrootd/XrdXrootdMonData.hh"
00020 #include <fstream>
00021 #include <iomanip>
00022 #include <netinet/in.h>
00023 #include <unistd.h>
00024
00025 using std::cerr;
00026 using std::cout;
00027 using std::endl;
00028 using std::fstream;
00029 using std::ios;
00030 using std::pair;
00031 using std::setw;
00032
00033 typedef pair<kXR_int32, kXR_int32> TimePair;
00034
00035 struct CalcTime {
00036 CalcTime(float f, kXR_int32 t, int e)
00037 : timePerTrace(f), begTimeNextWindow(t), endOffset(e) {}
00038 float timePerTrace;
00039 kXR_int32 begTimeNextWindow;
00040 int endOffset;
00041 };
00042
00043 TimePair
00044 decodeTime(const char* packet)
00045 {
00046 struct X {
00047 kXR_int32 endT;
00048 kXR_int32 begT;
00049 } x;
00050 memcpy(&x, packet+sizeof(kXR_int64), sizeof(X));
00051 return TimePair(ntohl(x.endT), ntohl(x.begT));
00052 }
00053
00054 CalcTime
00055 prepareTimestamp(const char* packet,
00056 int& offset,
00057 int len,
00058 kXR_int32& begTime)
00059 {
00060
00061 int x = offset;
00062 int noElems = 0;
00063 while ( static_cast<kXR_char>(*(packet+x)) != XROOTD_MON_WINDOW ) {
00064 if ( x >= len ) {
00065 cerr << "Error: expected time window packet (last packet)" << endl;
00066 exit(1);
00067 }
00068 x += TRACELEN;
00069 ++noElems;
00070 }
00071
00072
00073 TimePair t = decodeTime(packet+x);
00074 cout << "offset " << setw(5) << x
00075 << " - location of next timepair: {"
00076 << t.first << ", " << t.second << "}. "
00077 << noElems << " traces in between" << endl;
00078
00079 if ( begTime > t.first ) {
00080 cout << "Error: wrong time: " << begTime
00081 << " > " << t.first << " at offset " << x
00082 << ", will use begTime == endTime" << endl;
00083 begTime = t.first;
00084 }
00085
00086 float timePerTrace = ((float)(t.first - begTime)) / noElems;
00087 cout << "will use following time per trace = " << timePerTrace << endl;
00088
00089 return CalcTime(timePerTrace, t.second, x);
00090 }
00091
00092 void
00093 debugRWRequest(const char* packet, kXR_int32 timestamp, kXR_int64 offset)
00094 {
00095 struct X {
00096 kXR_int64 tOffset;
00097 kXR_int32 tLen;
00098 kXR_int32 dictId;
00099 } x;
00100 memcpy(&x, packet, sizeof(X));
00101 x.tOffset = ntohll(x.tOffset);
00102 x.tLen = ntohl(x.tLen);
00103 x.dictId = ntohl(x.dictId);
00104
00105 if ( x.tOffset < 0 ) {
00106 cerr << "Error negative offset" << endl;
00107 exit(1);
00108 }
00109 char rwReq = 'r';
00110 if ( x.tLen<0 ) {
00111 rwReq = 'w';
00112 x.tLen *= -1;
00113 }
00114 cout << "offset " << setw(5) << offset
00115 << " --> trace: offset=" << x.tOffset << " len=" << x.tLen
00116 << " rw=" << rwReq << " timestamp=" << timestamp << endl;
00117 }
00118
00119 void
00120 debugOpen(const char* packet,
00121 kXR_int32 timestamp,
00122 kXR_int64 offset)
00123 {
00124 kXR_int32 dictId;
00125 memcpy(&dictId,
00126 packet+sizeof(kXR_int64)+sizeof(kXR_int32),
00127 sizeof(kXR_int32));
00128 dictId = ntohl(dictId);
00129
00130 cout << "offset " << setw(5) << offset
00131 << " --> open " << " dictId = " << dictId
00132 << ", timestamp = " << timestamp << endl;
00133 }
00134
00135 void
00136 debugClose(const char* packet,
00137 kXR_int32 timestamp,
00138 kXR_int64 offset)
00139 {
00140 XrdXrootdMonTrace trace;
00141 memcpy(&trace, packet, sizeof(XrdXrootdMonTrace));
00142 kXR_unt32 dictId = ntohl(trace.arg2.dictid);
00143 kXR_unt32 tR = ntohl(trace.arg0.rTot[1]);
00144 kXR_unt32 tW = ntohl(trace.arg1.wTot);
00145 char rShift = trace.arg0.id[1];
00146 char wShift = trace.arg0.id[2];
00147 kXR_int64 realR = tR; realR = realR << rShift;
00148 kXR_int64 realW = tW; realW = realW << wShift;
00149
00150 cout << "offset " << setw(5) << offset
00151 << " --> close " << " dictId = " << dictId
00152 << ", timestamp = " << timestamp
00153 << ", total r " <<tR<< " shifted " << (int) rShift << ", or " << realR
00154 << ", total w " <<tW<< " shifted " << (int) wShift << ", or " << realW
00155 << endl;
00156 }
00157
00158
00159 void
00160 debugDictPacket(const char* packet, int len)
00161 {
00162 kXR_int32 x32;
00163 memcpy(&x32, packet, sizeof(kXR_int32));
00164 dictid_t dictId = ntohl(x32);
00165
00166 XrdMonDecDictInfo de(dictId, -1,
00167 packet+sizeof(kXR_int32),
00168 len-sizeof(kXR_int32),
00169 0);
00170 cout << "offset " << setw(5) << HDRLEN
00171 << " --> " << de << endl;
00172 }
00173
00174 void
00175 debugUserPacket(const char* packet, int len)
00176 {
00177 kXR_int32 x32;
00178 memcpy(&x32, packet, sizeof(kXR_int32));
00179 dictid_t dictId = ntohl(x32);
00180
00181 XrdMonDecUserInfo du(dictId, -1,
00182 packet+sizeof(kXR_int32),
00183 len-sizeof(kXR_int32),
00184 0);
00185 cout << "offset " << setw(5) << HDRLEN
00186 << " --> " << du << endl;
00187 }
00188
00189 void
00190 debugDisconnect(const char* packet, int len)
00191 {
00192 XrdXrootdMonTrace trace;
00193 memcpy(&trace, packet, sizeof(XrdXrootdMonTrace));
00194 kXR_int32 sec = ntohl(trace.arg1.buflen);
00195 kXR_unt32 dictId = ntohl(trace.arg2.dictid);
00196
00197 cout << "offset " << setw(5) << HDRLEN
00198 << " --> user disconnect, dict " << dictId
00199 << ", sec = " << sec << endl;
00200 }
00201
00202 void
00203 debugStagePacket(const char* packet, int)
00204 {
00205 cerr << "DebugStagePacket() not implemented" << endl;
00206 }
00207
00208 void
00209 debugTracePacket(const char* packet, int len)
00210 {
00211 if ( static_cast<kXR_char>(*packet) != XROOTD_MON_WINDOW ) {
00212 cerr << "Expected time window packet (1st packet), got "
00213 << (int) *packet << endl;
00214 return;
00215 }
00216 TimePair t = decodeTime(packet);
00217 cout << "offset " << setw(5) << HDRLEN
00218 << ", timepair: {" << t.first << ", " << t.second << "}" << endl;
00219
00220 kXR_int32 begTime = t.second;
00221 int offset = TRACELEN;
00222
00223 while ( offset < len ) {
00224 CalcTime ct = prepareTimestamp(packet, offset, len, begTime);
00225 int elemNo = 0;
00226 while ( offset<ct.endOffset ) {
00227 kXR_char infoType = static_cast<kXR_char>(*(packet+offset));
00228 kXR_int32 timestamp = begTime + (kXR_int32) (elemNo++ * ct.timePerTrace);
00229 if ( !(infoType & XROOTD_MON_RWREQUESTMASK) ) {
00230 cout << "offset " << setw(5) << offset
00231 << " --> XROOTD_MON_RWREQUESTMAST" << endl;
00232 debugRWRequest(packet+offset, timestamp, offset+HDRLEN);
00233 } else if ( infoType == XROOTD_MON_OPEN ) {
00234 cout << "offset " << setw(5) << offset
00235 << " --> XROOTD_MON_OPEN" << endl;
00236 debugOpen(packet+offset, timestamp, offset+HDRLEN);
00237 } else if ( infoType == XROOTD_MON_CLOSE ) {
00238 cout << "offset " << setw(5) << offset
00239 << " --> XROOTD_MON_CLOSE" << endl;
00240 debugClose(packet+offset, timestamp, offset+HDRLEN);
00241 } else if ( infoType == XROOTD_MON_DISC ) {
00242 debugDisconnect(packet+offset, offset+HDRLEN);
00243
00244 } else {
00245 cerr << "Unsupported infoType of trace packet: "
00246 << infoType << endl;
00247 return;
00248 }
00249 offset += TRACELEN;
00250 }
00251 begTime = ct.begTimeNextWindow;
00252 offset += TRACELEN;
00253 }
00254 }
00255
00256 int main(int argc, char* argv[])
00257 {
00258 if ( argc != 2 ) {
00259 cerr << "Expected input file path" << endl;
00260 return 1;
00261 }
00262 const char* fName = argv[1];
00263 if ( 0 != access(fName, F_OK) ) {
00264 cerr << "Cannot open " << fName << endl;
00265 return 2;
00266 }
00267
00268 fstream _file;
00269 _file.open(fName, ios::in|ios::binary);
00270 _file.seekg(0, ios::beg);
00271
00272
00273 char hBuffer[HDRLEN];
00274 _file.read(hBuffer, HDRLEN);
00275
00276
00277 XrdMonHeader header;
00278 header.decode(hBuffer);
00279 cout << "offset " << setw(5) << 0
00280 << " header:" << header << endl;
00281
00282 int len = header.packetLen() - HDRLEN;
00283
00284
00285 char packet[MAXPACKETSIZE];
00286 _file.read(packet, len);
00287
00288 switch (header.packetType() ) {
00289 case PACKET_TYPE_TRACE: { debugTracePacket(packet, len); break; }
00290 case PACKET_TYPE_DICT: { debugDictPacket(packet, len); break; }
00291 case PACKET_TYPE_STAGE: { debugStagePacket(packet, len); break; }
00292 case PACKET_TYPE_USER: { debugUserPacket(packet, len); break; }
00293 default: {
00294 cerr << "Invalid packet type " << header.packetType() << endl;
00295 return 1;
00296 }
00297 }
00298
00299 _file.close();
00300
00301 return 0;
00302 }