StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StWsLogger.cxx
1 #include "StWsLogger.h"
2 
3 #include <curl/curl.h>
4 
5 #include <unistd.h>
6 #include <cstdio>
7 #include <ctime>
8 #include <cstdlib>
9 #include <pwd.h>
10 #include <sys/time.h>
11 
12 #include <sstream>
13 
14 namespace {
15 
16 template <class T>
17 std::string toString(T& arg)
18 {
19  std::ostringstream os;
20  os << arg;
21  return os.str();
22 }
23 
24 template <class T>
25 std::string toString(T arg)
26 {
27  std::ostringstream os;
28  os << arg;
29  return os.str();
30 }
31 
32 template<class T>
33 T fromString(const std::string& s)
34 {
35  std::istringstream stream (s);
36  T t;
37  stream >> t;
38  return t;
39 }
40 
41 size_t curl_write_to_string(void *ptr, size_t size, size_t count, void *stream) {
42  ((std::string*)stream)->append((char*)ptr, 0, size*count);
43  return size*count;
44 }
45 
46 }
47 
48 StWsLogger::StWsLogger()
49  : mServiceUrl(""),
50  mJobID(""),
51  mTaskID(""),
52  mIsDisabled(false)
53 {
54  mServiceUrl = getServiceUrl();
55  mJobID = getJobID();
56  mTaskID = getTaskID();
57 }
58 
59 StWsLogger::~StWsLogger()
60 {
61 
62 }
63 
64 void StWsLogger::logEvent(LEVEL lvl, const picojson::object& evt, STAGE stg, bool nobacklog) {
65  if (mIsDisabled) { return; }
66 
67  picojson::object event;
68  event["timestamp"] = picojson::value(getTimeMs());
69  event["level_id"] = picojson::value((double)lvl);
70  event["stage_id"] = picojson::value((double)stg);
71  event["message"] = picojson::value(evt);
72 
73  picojson::value v(event);
74  std::string response;
75 
76  //std::cout << "*** WS_LOGGER: " << v.serialize() << std::endl; // FIXME
77 
78  return; // FIXME
79 
80  int ret = makeHttpPostCurl(
81  ( mServiceUrl + std::string("?action=event_append&task_id=") + mTaskID + std::string("&job_id=") + mJobID ).c_str(),
82  v.serialize(),
83  response
84  );
85 
86  if (ret != 0) {
87  // HTTP POST ERROR OCCURED, add evt to backlog
88  if (!nobacklog) {
89  mEventBackLog.push_back(v.serialize());
90  }
91  }
92 
93  checkBackLogs();
94 }
95 
96 void StWsLogger::logJobUpdate(const picojson::object& evt, bool nobacklog) {
97  if (mIsDisabled) { return; }
98 
99  picojson::object event;
100  event["timestamp"] = picojson::value(getTimeMs());
101  event["message"] = picojson::value(evt);
102 
103  picojson::value v(event);
104  std::string response;
105 
106  int ret = makeHttpPostCurl(
107  ( mServiceUrl + std::string("?action=job_add_info&task_id=") + mTaskID + std::string("&job_id=") + mJobID ).c_str(),
108  v.serialize(),
109  response
110  );
111 
112  if (ret != 0) {
113  // HTTP POST ERROR OCCURED, add evt to backlog
114  mJobUpdateBackLog.push_back(v.serialize());
115  }
116 
117  checkBackLogs();
118 }
119 
120 double StWsLogger::getTimeMs() const {
121  timeval tim;
122  gettimeofday(&tim, NULL);
123  double t1=tim.tv_sec+(tim.tv_usec/1000000.0);
124  return t1;
125 }
126 
127 std::string StWsLogger::getUserName() const {
128  register struct passwd *pw;
129  register uid_t uid;
130  uid = geteuid();
131  pw = getpwuid (uid);
132  if (pw) {
133  return (std::string(pw->pw_name));
134  }
135  return std::string("UNKNOWN");
136 }
137 
138 std::string StWsLogger::getHostName() const {
139  char buf[512];
140  gethostname(buf,sizeof buf);
141  return std::string(buf);
142 }
143 
144 void StWsLogger::setServiceUrl(const std::string& url) {
145  mServiceUrl = url;
146  if (!mServiceUrl.empty() && !mJobID.empty() && !mTaskID.empty()) { mIsDisabled = false; }
147  //std::cout << "WS_LOGGER_CHECK: " << mServiceUrl << ", " << mJobID << ", " << mTaskID << ", C: " << mIsDisabled << "\n";
148 }
149 
150 void StWsLogger::setJobID(const std::string& id) {
151  mJobID = id;
152  if (!mServiceUrl.empty() && !mJobID.empty() && !mTaskID.empty()) { mIsDisabled = false; }
153  //std::cout << "WS_LOGGER_CHECK: " << mServiceUrl << ", " << mJobID << ", " << mTaskID << ", C:" << mIsDisabled << "\n";
154 }
155 
156 void StWsLogger::setTaskID(const std::string& id) {
157  mTaskID = id;
158  if (!mServiceUrl.empty() && !mJobID.empty() && !mTaskID.empty()) { mIsDisabled = false; }
159  //std::cout << "WS_LOGGER_CHECK: " << mServiceUrl << ", " << mJobID << ", " << mTaskID << ", C: " << mIsDisabled << "\n";
160 }
161 
162 std::string StWsLogger::getServiceUrl() {
163  if (!mServiceUrl.empty()) { return mServiceUrl; }
164 
165  char* surl = 0;
166  surl = getenv("WS_LOG_URL");
167  if (surl != NULL) {
168  return std::string(surl);
169  }
170  //std::cout << "NO LOG URL, DISABLING WS_LOGGER\n";
171  mIsDisabled = true;
172  return std::string("");
173 }
174 
175 std::string StWsLogger::getJobID() {
176  if (!mJobID.empty()) { return mJobID; }
177 
178  char* jid = 0;
179  jid = getenv("WS_JOB_ID");
180  if (jid != NULL) {
181  return std::string(jid);
182  }
183  //std::cout << "NO JOB ID, DISABLING WS_LOGGER\n";
184  mIsDisabled = true;
185  return std::string("");
186 }
187 
188 std::string StWsLogger::getTaskID() {
189  if (!mTaskID.empty()) { return mTaskID; }
190 
191  char* tid = 0;
192  tid = getenv("WS_TASK_ID");
193  if (tid != NULL) {
194  return std::string(tid);
195  }
196  //std::cout << "NO TASK ID, DISABLING WS_LOGGER\n";
197  mIsDisabled = true;
198  return std::string("");
199 }
200 
201 int StWsLogger::makeHttpPostCurl(const char* url, const std::string& json_data, std::string& response) {
202  // no need to code proxy in, it is autodetected by libcurl (env.vars)
203 
204  CURL *curl;
205  CURLcode res;
206 
207  curl = curl_easy_init();
208  if (curl) {
209  curl_easy_setopt(curl, CURLOPT_URL, url);
210  }
211  curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
212  curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
213  curl_easy_setopt(curl, CURLOPT_POST, 1L);
214 // curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
215 
216  curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_write_to_string);
217  curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
218 
219  struct curl_slist *chunk = NULL;
220  chunk = curl_slist_append(chunk, "Expect:");
221  res = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
222 
223  curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json_data.c_str());
224  curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, json_data.length());
225 
226  res = curl_easy_perform(curl);
227  if(res != CURLE_OK) {
228  std::cerr << "HTTPS POST request failed: " << curl_easy_strerror(res) << std::endl;
229  return res;
230  }
231  curl_slist_free_all(chunk);
232  curl_easy_cleanup(curl);
233  return 0;
234 }
235 
236 void StWsLogger::checkBackLogs() {
237  if (!mEventBackLog.empty()) {
238  std::string response;
239  for (std::vector<std::string>::iterator it = mEventBackLog.begin(); it != mEventBackLog.end(); ++it) {
240  int ret = makeHttpPostCurl(
241  ( mServiceUrl + std::string("?action=event_append&task_id=") + mTaskID + std::string("&job_id=") + mJobID ).c_str(),
242  *it,
243  response
244  );
245  if (ret != 0) return;
246  it = mEventBackLog.erase(it);
247  }
248  }
249 
250  if (!mJobUpdateBackLog.empty()) {
251  std::string response;
252  for (std::vector<std::string>::iterator it = mJobUpdateBackLog.begin(); it != mJobUpdateBackLog.end(); ++it) {
253  int ret = makeHttpPostCurl(
254  ( mServiceUrl + std::string("?action=job_add_info&task_id=") + mTaskID + std::string("&job_id=") + mJobID ).c_str(),
255  *it,
256  response
257  );
258  if (ret != 0) return;
259  it = mJobUpdateBackLog.erase(it);
260  }
261  }
262 }