You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tubemq.apache.org by go...@apache.org on 2020/07/06 10:57:13 UTC

[incubator-tubemq] branch tubemq-client-cpp updated: [TUBEMQ-268] C++ SDK log module (#190)

This is an automated email from the ASF dual-hosted git repository.

gosonzhang pushed a commit to branch tubemq-client-cpp
in repository https://gitbox.apache.org/repos/asf/incubator-tubemq.git


The following commit(s) were added to refs/heads/tubemq-client-cpp by this push:
     new c64b336  [TUBEMQ-268] C++ SDK log module (#190)
c64b336 is described below

commit c64b3367fae24c0f76f5ed43ded8b9fb2a2c7c1c
Author: charlely <41...@users.noreply.github.com>
AuthorDate: Mon Jul 6 18:57:06 2020 +0800

    [TUBEMQ-268] C++ SDK log module (#190)
---
 .gitmodules                                        |   4 +
 .../tubemq-client-cpp/example/README.md            |  22 +++++
 .../tubemq-client-cpp/example/log/main.cc          |  46 +++++++++
 tubemq-client-twins/tubemq-client-cpp/inc/logger.h | 109 +++++++++++++++++++++
 .../tubemq-client-cpp/inc/noncopyable.h            |  37 +++++++
 .../tubemq-client-cpp/inc/singleton.h              |  60 ++++++++++++
 .../tubemq-client-cpp/inc/unique_seq_id.h          |  40 ++++++++
 .../tubemq-client-cpp/src/logger.cc                |  75 ++++++++++++++
 .../tubemq-client-cpp/third_party/log4cplus        |   1 +
 9 files changed, 394 insertions(+)

diff --git a/.gitmodules b/.gitmodules
index 417049c..c80f44d 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -2,3 +2,7 @@
 	path = tubemq-client-twins/tubemq-client-cpp/third_party/rapidjson
 	url = https://github.com/Tencent/rapidjson.git
 	tag = v1.1.0
+[submodule "tubemq-client-twins/tubemq-client-cpp/third_party/log4cplus"]
+	path = tubemq-client-twins/tubemq-client-cpp/third_party/log4cplus
+	url = https://github.com/log4cplus/log4cplus
+	tag = REL_2_0_5
diff --git a/tubemq-client-twins/tubemq-client-cpp/example/README.md b/tubemq-client-twins/tubemq-client-cpp/example/README.md
new file mode 100644
index 0000000..4998b5f
--- /dev/null
+++ b/tubemq-client-twins/tubemq-client-cpp/example/README.md
@@ -0,0 +1,22 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#Example#
+
+tubemq-client-cpp example. 
diff --git a/tubemq-client-twins/tubemq-client-cpp/example/log/main.cc b/tubemq-client-twins/tubemq-client-cpp/example/log/main.cc
new file mode 100644
index 0000000..f21d022
--- /dev/null
+++ b/tubemq-client-twins/tubemq-client-cpp/example/log/main.cc
@@ -0,0 +1,46 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <chrono>
+#include <exception>
+#include <iostream>
+#include <string>
+#include <thread>
+
+#include "logger.h"
+
+using namespace std;
+using namespace tubemq;
+
+void log() {
+  int i = 0;
+  while (1) {
+    LOG_ERROR("threadid:%ld, i:%d", std::this_thread::get_id(), i++);
+  }
+}
+
+int main() {
+  std::thread t1(log);
+  std::thread t2(log);
+  std::thread t3(log);
+  std::thread t4(log);
+  t1.join();
+  return 0;
+}
+
diff --git a/tubemq-client-twins/tubemq-client-cpp/inc/logger.h b/tubemq-client-twins/tubemq-client-cpp/inc/logger.h
new file mode 100644
index 0000000..44c28b7
--- /dev/null
+++ b/tubemq-client-twins/tubemq-client-cpp/inc/logger.h
@@ -0,0 +1,109 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef _TUBEMQ_LOG_FILE_
+#define _TUBEMQ_LOG_FILE_
+
+#include <string>
+#include <vector>
+
+namespace tubemq {
+class Logger;
+
+Logger& GetLogger();
+
+#define LOG_LEVEL(level, fmt, ...)                                                                          \
+  {                                                                                                         \
+    if (tubemq::GetLogger().IsEnable(level)) {                                                              \
+      tubemq::GetLogger().Write("[%s:%d][%s]" fmt, __func__, __LINE__, tubemq::Logger::Level2String(level), \
+                                ##__VA_ARGS__);                                                             \
+    }                                                                                                       \
+  }
+
+#define LOG_TRACE(fmt, ...) LOG_TUBE(tubemq::GetLogger(), tubemq::Logger::kTrace, fmt, ##__VA_ARGS__)
+#define LOG_DEBUG(fmt, ...) LOG_TUBE(tubemq::GetLogger(), tubemq::Logger::kDebug, fmt, ##__VA_ARGS__)
+#define LOG_INFO(fmt, ...) LOG_TUBE(tubemq::GetLogger(), tubemq::Logger::kInfo, fmt, ##__VA_ARGS__)
+#define LOG_WARN(fmt, ...) LOG_TUBE(tubemq::GetLogger(), tubemq::Logger::kWarn, fmt, ##__VA_ARGS__)
+#define LOG_ERROR(fmt, ...) LOG_TUBE(tubemq::GetLogger(), tubemq::Logger::kError, fmt, ##__VA_ARGS__)
+
+#define LOG_TUBE(logger, level, fmt, ...)                                                                      \
+  {                                                                                                            \
+    if (logger.IsEnable(level)) {                                                                              \
+      logger.Write("[%s:%d][%s]" fmt, __func__, __LINE__, tubemq::Logger::Level2String(level), ##__VA_ARGS__); \
+    }                                                                                                          \
+  }
+
+class Logger {
+ public:
+  enum Level
+  {
+    kTrace = 0,
+    kDebug = 1,
+    kInfo = 2,
+    kWarn = 3,
+    kError = 4,
+  };
+
+  // size: MB
+  Logger() : file_max_size_(100), file_num_(10), level_(kError), base_path_("tubemq"), instance_("TubeMQ") { setup(); }
+
+  ~Logger(void) {}
+
+  // path example: ../log/tubemq
+  // size: MB
+  bool Init(const std::string& path, Level level, uint32_t file_max_size = 100, uint32_t file_num = 10);
+
+  bool Write(const char* sFormat, ...) __attribute__((format(printf, 2, 3)));
+  inline bool WriteStream(const std::string& msg) { return writeStream(msg.c_str()); }
+
+  inline void SetInstance(const std::string& instance) { instance_ = instance; }
+  inline bool IsEnable(Level level) {
+    if (level_ <= level) {
+      return true;
+    } else {
+      return false;
+    }
+  }
+
+  static const char* Level2String(Level level) {
+    static const char* level_names[] = {
+        "TRACE",
+        "DEBUG"
+        "INFO",
+        "WARN",
+        "ERROR",
+    };
+    return level_names[level];
+  }
+
+ private:
+  void setup();
+  bool writeStream(const char* msg);
+
+ private:
+  uint32_t file_max_size_;
+  uint16_t file_num_;
+  uint8_t level_;
+
+  std::string base_path_;
+  std::string instance_;
+  std::string err_msg_;
+};
+}  // namespace tubemq
+#endif  // _TUBEMQ_LOG_FILE_
diff --git a/tubemq-client-twins/tubemq-client-cpp/inc/noncopyable.h b/tubemq-client-twins/tubemq-client-cpp/inc/noncopyable.h
new file mode 100644
index 0000000..9afbf52
--- /dev/null
+++ b/tubemq-client-twins/tubemq-client-cpp/inc/noncopyable.h
@@ -0,0 +1,37 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef _TUBUMQ_NONCOPYABLE_H
+#define _TUBUMQ_NONCOPYABLE_H
+
+namespace tubemq {
+
+class noncopyable {
+ public:
+  noncopyable(const noncopyable&) = delete;
+  void operator=(const noncopyable&) = delete;
+
+ protected:
+  noncopyable() = default;
+  ~noncopyable() = default;
+};
+
+}  // namespace tubemq
+
+#endif  // _TUBUMQ_NONCOPYABLE_H
diff --git a/tubemq-client-twins/tubemq-client-cpp/inc/singleton.h b/tubemq-client-twins/tubemq-client-cpp/inc/singleton.h
new file mode 100644
index 0000000..af3b0d4
--- /dev/null
+++ b/tubemq-client-twins/tubemq-client-cpp/inc/singleton.h
@@ -0,0 +1,60 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef _TUBEMQ_SINGLETON_H
+#define _TUBEMQ_SINGLETON_H
+
+#include <thread>
+#include <mutex>
+#include <assert.h>
+#include <stdlib.h>
+
+#include "noncopyable.h"
+
+namespace tubemq {
+
+template <typename T>
+class Singleton : noncopyable {
+ public:
+  Singleton() = delete;
+  ~Singleton() = delete;
+
+  static T& instance() {
+    std::call_once(once_, Singleton::init);
+    assert(value_ != nullptr);
+    return *value_;
+  }
+
+ private:
+  static void init() { value_ = new T(); }
+
+ private:
+  static std::once_flag once_;
+  static T* value_;
+};
+
+template <typename T>
+std::once_flag Singleton<T>::once_;
+
+template <typename T>
+T* Singleton<T>::value_ = nullptr;
+
+}  // namespace tubemq
+
+#endif  // _TUBEMQ_SINGLETON_H
diff --git a/tubemq-client-twins/tubemq-client-cpp/inc/unique_seq_id.h b/tubemq-client-twins/tubemq-client-cpp/inc/unique_seq_id.h
new file mode 100644
index 0000000..d836be1
--- /dev/null
+++ b/tubemq-client-twins/tubemq-client-cpp/inc/unique_seq_id.h
@@ -0,0 +1,40 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef TUBEMQ_UNIQUESEQID_H
+#define TUBEMQ_UNIQUESEQID_H
+
+#include <atomic>
+#include <stdint.h>
+
+namespace tubemq {
+
+class UniqueSeqId {
+ public:
+  UniqueSeqId() : id(0) {}
+
+  uint32_t Next() { return id.fetch_add(1, std::memory_order_relaxed); }
+
+ protected:
+  std::atomic<uint32_t> id;
+};
+
+}  // namespace tubemq
+
+#endif
diff --git a/tubemq-client-twins/tubemq-client-cpp/src/logger.cc b/tubemq-client-twins/tubemq-client-cpp/src/logger.cc
new file mode 100644
index 0000000..c1860df
--- /dev/null
+++ b/tubemq-client-twins/tubemq-client-cpp/src/logger.cc
@@ -0,0 +1,75 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "logger.h"
+
+#include <log4cplus/fileappender.h>
+#include <log4cplus/layout.h>
+#include <log4cplus/logger.h>
+#include <log4cplus/loggingmacros.h>
+#include <stdarg.h>
+
+#include <string>
+
+namespace tubemq {
+
+Logger tubemq_logger;
+
+Logger& GetLogger() { return tubemq_logger; }
+
+bool Logger::Init(const std::string& path, Logger::Level level, uint32_t file_max_size, uint32_t file_num) {
+  base_path_ = path;
+  file_max_size_ = file_max_size;
+  file_num_ = file_num;
+  level_ = level;
+  setup();
+  return true;
+}
+
+bool Logger::Write(const char* format, ...) {
+  char buf[8192];
+  buf[sizeof(buf) - 1] = 0;
+  va_list ap;
+  va_start(ap, format);
+  vsnprintf(buf, sizeof(buf) - 1, format, ap);
+  va_end(ap);
+  return writeStream(buf);
+}
+
+bool Logger::writeStream(const char* log) {
+  auto logger = log4cplus::Logger::getInstance(instance_);
+  log4cplus::tostringstream _log4cplus_buf;
+  _log4cplus_buf << log;
+  logger.forcedLog(log4cplus::TRACE_LOG_LEVEL, _log4cplus_buf.str());
+  return true;
+}
+
+void Logger::setup() {
+  bool immediate_fush = true;
+  std::string pattern = "[%D{%Y-%m-%d %H:%M:%S.%q}][tid:%t]%m%n";
+  auto logger_d = log4cplus::Logger::getInstance(instance_);
+  logger_d.setLogLevel(log4cplus::TRACE_LOG_LEVEL);
+  log4cplus::helpers::SharedObjectPtr<log4cplus::Appender> append_d(
+      new log4cplus::RollingFileAppender(base_path_ + ".log", file_max_size_, file_num_, immediate_fush));
+  std::unique_ptr<log4cplus::Layout> layout_d(new log4cplus::PatternLayout(pattern));
+  append_d->setLayout(std::move(layout_d));
+  logger_d.addAppender(append_d);
+}
+
+}  // namespace tubemq
diff --git a/tubemq-client-twins/tubemq-client-cpp/third_party/log4cplus b/tubemq-client-twins/tubemq-client-cpp/third_party/log4cplus
new file mode 160000
index 0000000..76ff7e6
--- /dev/null
+++ b/tubemq-client-twins/tubemq-client-cpp/third_party/log4cplus
@@ -0,0 +1 @@
+Subproject commit 76ff7e68c35e277440d414ba782eceedad8db7b1