1 /* Copyright (C) 2014 InfiniDB, Inc.
2 Copyright (C) 2016 MariaDB Corporation
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; version 2 of
7 the License.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 MA 02110-1301, USA. */
18
19 /*****************************************************************************
20 * $Id: tracer.cpp 1823 2013-01-21 14:13:09Z rdempsey $
21 *
22 ****************************************************************************/
23
24 #include <iostream>
25 #include <fstream>
26 #include <algorithm>
27
28 #ifdef _MSC_VER
29 #include <process.h>
30 #include <ctime>
31 #endif
32
33 #include <unistd.h>
34
35 #define TRACER_DLLEXPORT
36 #include "tracer.h"
37 #undef TRACER_DLLEXPORT
38
39 #include "mcsconfig.h"
40
41 using namespace std;
42
43 namespace BRM
44 {
45 #ifdef BRM_INFO
46 std::ofstream brmlog(string(MCSLOGDIR) + "/brm.log", std::ios::app);
47
Tracer(const std::string & file,int line,const std::string & msg,bool debug,bool writeNow)48 Tracer::Tracer(const std::string& file, int line, const std::string& msg, bool debug, bool writeNow): fFileName(file), fLine(line), fMsg(msg), fDebug(debug), fpid(getpid())
49 {
50 if (writeNow)
51 writeBegin();
52 }
53
~Tracer()54 Tracer::~Tracer()
55 {
56 writeEnd();
57 }
58
59
printIntVec(const pair<string,const int * > & p)60 void printIntVec(const pair<string, const int*>& p)
61 {
62 brmlog << p.first << ": (" << *p.second << ") ";
63 }
64
printBoolVec(const pair<string,const bool * > & p)65 void printBoolVec(const pair<string, const bool*>& p)
66 {
67 brmlog << p.first << ": (" << *p.second << ") ";
68 }
69
printStrVec(const pair<string,const string * > & p)70 void printStrVec(const pair<string, const string*>& p)
71 {
72 brmlog << p.first << ": (" << *p.second << ") ";
73 }
74
printShortVec(const pair<string,const short * > & p)75 void printShortVec(const pair<string, const short*>& p)
76 {
77 brmlog << p.first << ": (" << *p.second << ") ";
78 }
79
printInt64Vec(const pair<string,const int64_t * > & p)80 void printInt64Vec(const pair<string, const int64_t*>& p)
81 {
82 brmlog << p.first << ": (" << *p.second << ") ";
83 }
84
85
writeBegin()86 void Tracer::writeBegin()
87 {
88 brmlog << timeStamp() << fpid << ":" << fFileName << "@" << fLine << " " << fMsg << " begin - ";
89 for_each(fInputs.begin(), fInputs.end(), printIntVec);
90 for_each(fBoolInputs.begin(), fBoolInputs.end(), printBoolVec);
91 for_each(fStrInputs.begin(), fStrInputs.end(), printStrVec);
92 for_each(fShortInputs.begin(), fShortInputs.end(), printShortVec);
93 for_each(fInt64Inputs.begin(), fInt64Inputs.end(), printInt64Vec);
94 brmlog << endl << flush;
95
96 }
97
writeEnd()98 void Tracer::writeEnd()
99 {
100 brmlog << timeStamp() << fpid << ":" << fFileName << " " << fMsg << " end ";
101
102 if (! fOutputs.empty() || ! fBoolOutputs.empty())
103 brmlog << "- ";
104
105 for_each(fOutputs.begin(), fOutputs.end(), printIntVec);
106 for_each(fBoolOutputs.begin(), fBoolOutputs.end(), printBoolVec);
107 for_each(fShortOutputs.begin(), fShortOutputs.end(), printShortVec);
108 for_each(fInt64Outputs.begin(), fInt64Outputs.end(), printInt64Vec);
109 brmlog << endl << flush;
110
111 }
112
writeDirect(const std::string & msg)113 void Tracer::writeDirect(const std::string& msg)
114 {
115 brmlog << msg << endl;
116 }
117
timeStamp()118 string Tracer::timeStamp()
119 {
120 time_t outputTime;
121 time(&outputTime);
122 string datestr(ctime(&outputTime));
123
124 try
125 {
126 //replace newline
127 return datestr.replace(datestr.length() - 1, 1, string(":"));
128 }
129 catch (exception& ex)
130 {
131 size_t tries = 3;
132
133 while (!datestr.length() && tries--)
134 datestr = ctime(&outputTime);
135
136 if (datestr.length())
137 return datestr.replace(datestr.length() - 1, 1, string(":"));
138 else
139 {
140 std::cerr << __FILE__ << "@" << __LINE__ << " " << ex.what() << " ";
141 cerr << datestr << " length " << datestr.length() << " Source: ";
142 cerr << fFileName << "@" << fLine << " " << fMsg << endl;
143 return string("timestamp error:");
144 }
145 }
146 }
147
148
addInput(const string & name,const int * value)149 void Tracer::addInput(const string& name, const int* value)
150 {
151 fInputs.push_back(make_pair(name, value));
152 }
153
addInput(const string & name,const string * value)154 void Tracer::addInput(const string& name, const string* value)
155 {
156 fStrInputs.push_back(make_pair(name, value));
157 }
158
addInput(const string & name,const bool * value)159 void Tracer::addInput(const string& name, const bool* value)
160 {
161 fBoolInputs.push_back(make_pair(name, value));
162 }
163
addInput(const string & name,const short * value)164 void Tracer::addInput(const string& name, const short* value)
165 {
166 fShortInputs.push_back(make_pair(name, value));
167 }
168
addInput(const string & name,const int64_t * value)169 void Tracer::addInput(const string& name, const int64_t* value)
170 {
171 fInt64Inputs.push_back(make_pair(name, value));
172 }
173
174
addOutput(const string & name,const int * value)175 void Tracer::addOutput(const string& name, const int* value)
176 {
177 fOutputs.push_back(make_pair(name, value));
178 }
179
addOutput(const string & name,const bool * value)180 void Tracer::addOutput(const string& name, const bool* value)
181 {
182 fBoolOutputs.push_back(make_pair(name, value));
183 }
184
addOutput(const string & name,const short * value)185 void Tracer::addOutput(const string& name, const short* value)
186 {
187 fShortOutputs.push_back(make_pair(name, value));
188 }
189
addOutput(const string & name,const int64_t * value)190 void Tracer::addOutput(const string& name, const int64_t* value)
191 {
192 fInt64Outputs.push_back(make_pair(name, value));
193 }
194
195 #endif
196
197 } //namespace
198