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