Skip to content

Commit 9fb204d

Browse files
[C++] Add C++ single file logger factory (#10712)
* Add SampleFileLogger C++ example * Expose SingleFileLoggerFactory as the public interface * Make logger factory public * Change logger factory's name * Use PImpl idiom for LoggerFactory classes
1 parent 9118643 commit 9fb204d

17 files changed

+280
-27
lines changed

examples/CMakeLists.txt

+6
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ set(SAMPLE_PRODUCER_SOURCES
3737
SampleProducer.cc
3838
)
3939

40+
set(SAMPLE_FILE_LOGGER_SOURCES
41+
SampleFileLogger.cc
42+
)
43+
4044
set(SAMPLE_PRODUCER_C_SOURCES
4145
SampleProducerCApi.c
4246
)
@@ -57,6 +61,7 @@ add_executable(SampleAsyncProducer ${SAMPLE_ASYNC_PRODUCER_SOURCES})
5761
add_executable(SampleConsumer ${SAMPLE_CONSUMER_SOURCES})
5862
add_executable(SampleConsumerListener ${SAMPLE_CONSUMER_LISTENER_SOURCES})
5963
add_executable(SampleProducer ${SAMPLE_PRODUCER_SOURCES})
64+
add_executable(SampleFileLogger ${SAMPLE_FILE_LOGGER_SOURCES})
6065
add_executable(SampleProducerCApi ${SAMPLE_PRODUCER_C_SOURCES})
6166
add_executable(SampleConsumerCApi ${SAMPLE_CONSUMER_C_SOURCES})
6267
add_executable(SampleConsumerListenerCApi ${SAMPLE_CONSUMER_LISTENER_C_SOURCES})
@@ -66,6 +71,7 @@ target_link_libraries(SampleAsyncProducer ${CLIENT_LIBS} pulsarShared)
6671
target_link_libraries(SampleConsumer ${CLIENT_LIBS} pulsarShared)
6772
target_link_libraries(SampleConsumerListener ${CLIENT_LIBS} pulsarShared)
6873
target_link_libraries(SampleProducer ${CLIENT_LIBS} pulsarShared)
74+
target_link_libraries(SampleFileLogger ${CLIENT_LIBS} pulsarShared)
6975
target_link_libraries(SampleProducerCApi ${CLIENT_LIBS} pulsarShared)
7076
target_link_libraries(SampleConsumerCApi ${CLIENT_LIBS} pulsarShared)
7177
target_link_libraries(SampleConsumerListenerCApi ${CLIENT_LIBS} pulsarShared)

examples/SampleAsyncProducer.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ int main() {
3535
Client client("pulsar://localhost:6650");
3636

3737
Producer producer;
38-
Result result = client.createProducer("persistent://prop/r1/ns1/my-topic", producer);
38+
Result result = client.createProducer("persistent://public/default/my-topic", producer);
3939
if (result != ResultOk) {
4040
LOG_ERROR("Error creating producer: " << result);
4141
return -1;

examples/SampleConsumer.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ int main() {
3030
Client client("pulsar://localhost:6650");
3131

3232
Consumer consumer;
33-
Result result = client.subscribe("persistent://prop/r1/ns1/my-topic", "consumer-1", consumer);
33+
Result result = client.subscribe("persistent://public/default/my-topic", "consumer-1", consumer);
3434
if (result != ResultOk) {
3535
LOG_ERROR("Failed to subscribe: " << result);
3636
return -1;

examples/SampleConsumerListener.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ int main() {
3838
Consumer consumer;
3939
ConsumerConfiguration config;
4040
config.setMessageListener(listener);
41-
Result result = client.subscribe("persistent://prop/r1/ns1/my-topic", "consumer-1", config, consumer);
41+
Result result = client.subscribe("persistent://public/default/my-topic", "consumer-1", config, consumer);
4242
if (result != ResultOk) {
4343
LOG_ERROR("Failed to subscribe: " << result);
4444
return -1;

examples/SampleFileLogger.cc

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
#include <pulsar/Client.h>
20+
21+
using namespace pulsar;
22+
23+
int main(int argc, char* argv[]) {
24+
ClientConfiguration clientConf;
25+
// The logs whose level is >= INFO will be written to pulsar-cpp-client.log
26+
clientConf.setLogger(new FileLoggerFactory(Logger::Level::LEVEL_INFO, "pulsar-cpp-client.log"));
27+
28+
Client client("pulsar://localhost:6650", clientConf);
29+
Producer producer;
30+
client.createProducer("my-topic", producer); // just to create some logs
31+
client.close();
32+
return 0;
33+
}

examples/SampleProducer.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ int main() {
3030
Client client("pulsar://localhost:6650");
3131

3232
Producer producer;
33-
Result result = client.createProducer("persistent://prop/r1/ns1/my-topic", producer);
33+
Result result = client.createProducer("persistent://public/default/my-topic", producer);
3434
if (result != ResultOk) {
3535
LOG_ERROR("Error creating producer: " << result);
3636
return -1;

include/pulsar/Client.h

+2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
#include <pulsar/MessageBuilder.h>
2929
#include <pulsar/ClientConfiguration.h>
3030
#include <pulsar/Schema.h>
31+
#include <pulsar/ConsoleLoggerFactory.h>
32+
#include <pulsar/FileLoggerFactory.h>
3133
#include <string>
3234

3335
namespace pulsar {

include/pulsar/SimpleLoggerFactory.h renamed to include/pulsar/ConsoleLoggerFactory.h

+9-6
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323

2424
namespace pulsar {
2525

26+
class ConsoleLoggerFactoryImpl;
27+
2628
/**
2729
* The default LoggerFactory of Client if `USE_LOG4CXX` macro was not defined during compilation.
2830
*
@@ -37,22 +39,23 @@ namespace pulsar {
3739
* level simply.
3840
*
3941
* ```c++
40-
* #include <pulsar/SimpleLoggerFactory.h>
42+
* #include <pulsar/ConsoleLoggerFactory.h>
4143
*
4244
* ClientConfiguration conf;
43-
* conf.setLogger(new SimpleLoggerFactory(Logger::LEVEL_DEBUG));
45+
* conf.setLogger(new ConsoleLoggerFactory(Logger::LEVEL_DEBUG));
4446
* Client client("pulsar://localhost:6650", conf);
4547
* ```
4648
*/
47-
class SimpleLoggerFactory : public LoggerFactory {
49+
class PULSAR_PUBLIC ConsoleLoggerFactory : public LoggerFactory {
4850
public:
49-
explicit SimpleLoggerFactory() = default;
50-
explicit SimpleLoggerFactory(Logger::Level level) : level_(level) {}
51+
explicit ConsoleLoggerFactory(Logger::Level level = Logger::LEVEL_INFO);
52+
53+
~ConsoleLoggerFactory();
5154

5255
Logger* getLogger(const std::string& fileName) override;
5356

5457
private:
55-
Logger::Level level_{Logger::LEVEL_INFO};
58+
std::unique_ptr<ConsoleLoggerFactoryImpl> impl_;
5659
};
5760

5861
} // namespace pulsar

include/pulsar/FileLoggerFactory.h

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
#pragma once
21+
22+
#include <pulsar/Logger.h>
23+
24+
namespace pulsar {
25+
26+
class FileLoggerFactoryImpl;
27+
28+
/**
29+
* A logger factory that is appending logs to a single file.
30+
*
31+
* The log format is "yyyy-mm-dd hh:MM:ss.xxx <level> <thread-id> <file>:<line> | <msg>", like
32+
*
33+
* ```
34+
* 2021-03-24 17:35:46.571 INFO [0x10a951e00] ConnectionPool:85 | Created connection for ...
35+
* ```
36+
*
37+
* Example:
38+
*
39+
* ```c++
40+
* #include <pulsar/FileLoggerFactory.h>
41+
*
42+
* ClientConfiguration conf;
43+
* conf.setLogger(new FileLoggerFactory(Logger::LEVEL_DEBUG, "pulsar-client-cpp.log"));
44+
* Client client("pulsar://localhost:6650", conf);
45+
* ```
46+
*/
47+
class PULSAR_PUBLIC FileLoggerFactory : public pulsar::LoggerFactory {
48+
public:
49+
/**
50+
* Create a FileLoggerFactory instance.
51+
*
52+
* @param level the log level
53+
* @param logFilePath the log file's path
54+
*/
55+
FileLoggerFactory(Logger::Level level, const std::string& logFilePath);
56+
57+
~FileLoggerFactory();
58+
59+
pulsar::Logger* getLogger(const std::string& filename) override;
60+
61+
private:
62+
std::unique_ptr<FileLoggerFactoryImpl> impl_;
63+
};
64+
65+
} // namespace pulsar

lib/ClientImpl.cc

+3-3
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
#include "PartitionedConsumerImpl.h"
2727
#include "MultiTopicsConsumerImpl.h"
2828
#include "PatternMultiTopicsConsumerImpl.h"
29-
#include <pulsar/SimpleLoggerFactory.h>
29+
#include <pulsar/ConsoleLoggerFactory.h>
3030
#include <boost/algorithm/string/predicate.hpp>
3131
#include <sstream>
3232
#include <lib/HTTPLookupService.h>
@@ -101,11 +101,11 @@ ClientImpl::ClientImpl(const std::string& serviceUrl, const ClientConfiguration&
101101
loggerFactory = Log4CxxLoggerFactory::create(clientConfiguration_.getLogConfFilePath());
102102
} else {
103103
// Use default simple console logger
104-
loggerFactory.reset(new SimpleLoggerFactory);
104+
loggerFactory.reset(new ConsoleLoggerFactory);
105105
}
106106
#else
107107
// Use default simple console logger
108-
loggerFactory.reset(new SimpleLoggerFactory);
108+
loggerFactory.reset(new ConsoleLoggerFactory);
109109
#endif
110110
}
111111
LogUtils::setLoggerFactory(std::move(loggerFactory));

lib/ConsoleLoggerFactory.cc

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
#include <pulsar/ConsoleLoggerFactory.h>
21+
#include "lib/ConsoleLoggerFactoryImpl.h"
22+
23+
namespace pulsar {
24+
25+
ConsoleLoggerFactory::ConsoleLoggerFactory(Logger::Level level)
26+
: impl_(new ConsoleLoggerFactoryImpl(level)) {}
27+
28+
ConsoleLoggerFactory::~ConsoleLoggerFactory() {}
29+
30+
Logger* ConsoleLoggerFactory::getLogger(const std::string& fileName) { return impl_->getLogger(fileName); }
31+
32+
} // namespace pulsar

lib/ConsoleLoggerFactoryImpl.h

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
#pragma once
21+
22+
#include <pulsar/Logger.h>
23+
#include "lib/SimpleLogger.h"
24+
25+
namespace pulsar {
26+
27+
class ConsoleLoggerFactoryImpl {
28+
public:
29+
ConsoleLoggerFactoryImpl(Logger::Level level) : level_(level) {}
30+
31+
Logger* getLogger(const std::string& fileName) { return new SimpleLogger(std::cout, fileName, level_); }
32+
33+
private:
34+
Logger::Level level_;
35+
};
36+
37+
} // namespace pulsar

lib/FileLoggerFactory.cc

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
#include <pulsar/FileLoggerFactory.h>
20+
#include "lib/FileLoggerFactoryImpl.h"
21+
22+
namespace pulsar {
23+
24+
FileLoggerFactory::FileLoggerFactory(Logger::Level level, const std::string& logFilePath)
25+
: impl_(new FileLoggerFactoryImpl(level, logFilePath)) {}
26+
27+
FileLoggerFactory::~FileLoggerFactory() {}
28+
29+
Logger* FileLoggerFactory::getLogger(const std::string& filename) { return impl_->getLogger(filename); }
30+
31+
} // namespace pulsar

lib/FileLoggerFactoryImpl.h

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
#pragma once
20+
21+
#include <fstream>
22+
#include <ios>
23+
#include <string>
24+
#include <pulsar/Logger.h>
25+
26+
#include "lib/SimpleLogger.h"
27+
28+
namespace pulsar {
29+
30+
class FileLoggerFactoryImpl {
31+
public:
32+
FileLoggerFactoryImpl(Logger::Level level, const std::string& logFilePath)
33+
: level_(level), os_(logFilePath, std::ios_base::out | std::ios_base::app) {}
34+
35+
~FileLoggerFactoryImpl() { os_.close(); }
36+
37+
Logger* getLogger(const std::string& filename) { return new SimpleLogger(os_, filename, level_); }
38+
39+
private:
40+
const Logger::Level level_;
41+
std::ofstream os_;
42+
};
43+
44+
} // namespace pulsar

lib/LogUtils.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121
#include <atomic>
2222
#include <iostream>
23-
#include <pulsar/SimpleLoggerFactory.h>
23+
#include <pulsar/ConsoleLoggerFactory.h>
2424

2525
#include "Log4CxxLogger.h"
2626

@@ -50,7 +50,7 @@ void LogUtils::setLoggerFactory(std::unique_ptr<LoggerFactory> loggerFactory) {
5050

5151
LoggerFactory* LogUtils::getLoggerFactory() {
5252
if (s_loggerFactory.load() == nullptr) {
53-
std::unique_ptr<LoggerFactory> newFactory(new SimpleLoggerFactory());
53+
std::unique_ptr<LoggerFactory> newFactory(new ConsoleLoggerFactory());
5454
setLoggerFactory(std::move(newFactory));
5555
}
5656
return s_loggerFactory.load();

0 commit comments

Comments
 (0)