resource: Disable logging if not enabled
[platform/upstream/iotivity.git] / resource / oc_logger / cpp / oc_ostream_logger.cpp
1 //******************************************************************
2 //
3 // Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
4 //
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 //
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
10 //
11 //      http://www.apache.org/licenses/LICENSE-2.0
12 //
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
18 //
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20
21 #include "oc_logger.hpp"
22 #include "targets/oc_ostream_logger.h"
23
24 #include <cstdio>
25 #include <cstdlib>
26
27 #include <mutex>
28 #include <memory>
29 #include <sstream>
30 #include <iostream>
31
32 namespace {
33
34 struct oc_ostream_logger_ctx
35 {
36  std::ostream*  os_ptr;
37  std::ostream&  os;
38
39  std::mutex     mutex;
40
41  oc_ostream_logger_ctx(std::ostream *here)
42   : os_ptr(here),
43     os(*os_ptr)
44  {}
45 };
46
47 } // namespace
48
49 /* Courtesy-function: */
50 oc_log_ctx_t *oc_make_ostream_logger()
51 {
52  return oc_log_make_ctx(
53             nullptr,
54             OC_LOG_ALL,
55             oc_ostream_log_init,
56             oc_ostream_log_destroy,
57             oc_ostream_log_flush,
58             oc_ostream_log_set_level,
59             oc_ostream_log_write,
60             oc_ostream_log_set_module
61         );
62 }
63
64 int oc_ostream_log_init(oc_log_ctx_t *ctx, void *world)
65 try
66 {
67  auto *target = reinterpret_cast<std::ostream *>(world);
68
69  if(nullptr == world)
70  {
71 #ifdef TB_LOG
72   target = &std::cout;
73 #else
74   static std::ostream nullstream(0);
75   target = &nullstream;
76 #endif
77  }
78
79  oc_ostream_logger_ctx *my_ctx = new oc_ostream_logger_ctx(target);
80
81  ctx->ctx = static_cast<void *>(my_ctx);
82
83  return 1;
84 }
85 catch(...)
86 {
87  return 0;
88 }
89
90 void oc_ostream_log_destroy(oc_log_ctx_t *ctx)
91 try
92 {
93  static std::mutex dtor_mtx;
94
95  oc_ostream_logger_ctx *lctx = static_cast<oc_ostream_logger_ctx *>(ctx->ctx);
96
97  {
98  std::unique_lock<std::mutex> ul(dtor_mtx);
99
100  lctx->os << std::flush;
101
102  delete lctx;
103  }
104 }
105 catch(...)
106 {
107 }
108
109 void oc_ostream_log_flush(oc_log_ctx_t *ctx)
110 try
111 {
112  oc_ostream_logger_ctx *lctx = static_cast<oc_ostream_logger_ctx *>(ctx->ctx);
113
114  std::lock_guard<std::mutex> lg(lctx->mutex);
115
116  lctx->os << std::flush;
117 }
118 catch(...)
119 {
120 }
121
122 void oc_ostream_log_set_level(oc_log_ctx_t * /*ctx*/, const int /*level*/)
123 try
124 {
125  /* We don't have any special thing we need to do when a log level changes. */
126  return;
127 }
128 catch(...)
129 {
130 }
131
132 size_t oc_ostream_log_write(oc_log_ctx_t *ctx, const int level, const char *msg)
133 try
134 {
135  oc_ostream_logger_ctx *lctx = static_cast<oc_ostream_logger_ctx *>(ctx->ctx);
136
137  std::lock_guard<std::mutex> lg(lctx->mutex);
138
139  std::ostringstream os;
140
141  os << level << ": ";
142
143  if(nullptr != ctx->module_name)
144   os << '[' << ctx->module_name << "] ";
145
146  os << msg << '\n';
147
148  lctx->os << os.str().c_str();
149
150  return 1 + os.str().length();
151 }
152 catch(...)
153 {
154  return 0;
155 }
156
157 int oc_ostream_log_set_module(oc_log_ctx_t * /*ctx*/,
158                               const char * /*module_name*/)
159 try
160 {
161  // Nothing special needs to happen for a module name change:
162  return 1;
163 }
164 catch(...)
165 {
166  return 0;
167 }
168
169 int oc_ostream_log_lock(oc_log_ctx_t *ctx)
170 try
171 {
172  oc_ostream_logger_ctx *lctx = static_cast<oc_ostream_logger_ctx *>(ctx->ctx);
173
174  lctx->mutex.lock();
175
176  return 1;
177 }
178 catch(...)
179 {
180  return 0;
181 }
182
183 int oc_ostream_log_unlock(oc_log_ctx_t *ctx)
184 try
185 {
186  oc_ostream_logger_ctx *lctx = static_cast<oc_ostream_logger_ctx *>(ctx->ctx);
187
188  lctx->mutex.unlock();
189
190  return 1;
191 }
192 catch(...)
193 {
194  return 0;
195 }
196
197 int oc_ostream_log_try_lock(oc_log_ctx_t *ctx)
198 try
199 {
200  oc_ostream_logger_ctx *lctx = static_cast<oc_ostream_logger_ctx *>(ctx->ctx);
201
202  return lctx->mutex.try_lock();
203 }
204 catch(...)
205 {
206  return 0;
207 }