Skip to content

Commit 9c4f0a5

Browse files
committed
Restructured logging code into a new subdirectory.
1 parent fd5e7d5 commit 9c4f0a5

File tree

8 files changed

+329
-0
lines changed

8 files changed

+329
-0
lines changed

CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -112,3 +112,4 @@ message(STATUS " CPP-NETLIB_DISABLE_LOGGING: ${CPP-NETLIB_DISABLE_LOGGING}\t(
112112

113113
add_subdirectory(uri)
114114
add_subdirectory(message)
115+
add_subdirectory(logging)

logging/CMakeLists.txt

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Copyright (c) Glyn Matthews 2012.
2+
# Distributed under the Boost Software License, Version 1.0.
3+
# (See accompanying file LICENSE_1_0.txt or copy at
4+
# http://www.boost.org/LICENSE_1_0.txt)
5+
6+
add_subdirectory(src)
7+
8+
if(CPP-NETLIB_BUILD_TESTS)
9+
enable_testing()
10+
add_subdirectory(test)
11+
endif(CPP-NETLIB_BUILD_TESTS)

logging/src/CMakeLists.txt

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Copyright (c) Glyn Matthews 2012.
2+
# Distributed under the Boost Software License, Version 1.0.
3+
# (See accompanying file LICENSE_1_0.txt or copy at
4+
# http://www.boost.org/LICENSE_1_0.txt)
5+
6+
if (${CMAKE_CXX_COMPILER_ID} MATCHES GNU)
7+
if (HAVE_STD11)
8+
set(CPP-NETLIB_CXXFLAGS "-Wall -std=c++11")
9+
elseif (HAVE_STD0X)
10+
set(CPP-NETLIB_CXXFLAGS "-Wall -std=c++0x")
11+
endif()
12+
elseif (${CMAKE_CXX_COMPILER_ID} MATCHES Clang)
13+
CHECK_CXX_COMPILER_FLAG(-std=c++11 HAVE_STD11)
14+
set(CPP-NETLIB_CXXFLAGS "-Wall -std=c++11 -stdlib=libc++")
15+
set(CPP-NETLIB_CXXFLAGS "-Wall -std=c++11 -stdlib=libc++")
16+
endif()
17+
18+
include_directories(${CPP-NETLIB_SOURCE_DIR}/logging/src)
19+
set(CPP-NETLIB_LOGGING_SRCS logging.cpp)
20+
add_library(cppnetlib-logging ${CPP-NETLIB_LOGGING_SRCS})
21+
foreach (src_file ${CPP-NETLIB_LOGGING_SRCS})
22+
if (${CMAKE_CXX_COMPILER_ID} MATCHES GNU)
23+
set_source_files_properties(${src_file}
24+
PROPERTIES COMPILE_FLAGS ${CPP-NETLIB_CXXFLAGS})
25+
elseif (${CMAKE_CXX_COMPILER_ID} MATCHES Clang)
26+
set_source_files_properties(${src_file}
27+
PROPERTIES COMPILE_FLAGS ${CPP-NETLIB_CXXFLAGS})
28+
endif()
29+
endforeach(src_file)

logging/src/logging.cpp

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// Copyright 2011 A. Joel Lamotte <[email protected]>.
2+
// Distributed under the Boost Software License, Version 1.0.
3+
// (See accompanying file LICENSE_1_0.txt or copy at
4+
// http://www.boost.org/LICENSE_1_0.txt)
5+
6+
#ifdef NETWORK_NO_LIB
7+
#undef NETWORK_NO_LIB
8+
#endif
9+
10+
#include <iostream>
11+
#include <memory>
12+
#include <network/logging/logging.hpp>
13+
14+
namespace network { namespace logging {
15+
16+
const char* log_record::UNKNOWN_FILE_NAME = "unknown";
17+
18+
19+
namespace handler
20+
{
21+
namespace
22+
{
23+
void std_log_handler( const log_record& log )
24+
{
25+
std::cerr << "[network " << log.filename() << ":" << log.line() << "] "
26+
<< log.message() << std::endl;
27+
}
28+
}
29+
30+
log_record_handler get_std_log_handler() { return &std_log_handler; }
31+
log_record_handler get_default_log_handler() { return &std_log_handler; }
32+
}
33+
34+
35+
namespace
36+
{
37+
// the log handler have to manage itself the thread safety on call
38+
static auto current_log_record_handler = std::make_shared<log_record_handler>( &handler::std_log_handler );
39+
40+
}
41+
42+
43+
void set_log_record_handler( log_record_handler handler )
44+
{
45+
current_log_record_handler = std::make_shared<log_record_handler>( handler );
46+
}
47+
48+
void log( const log_record& log )
49+
{
50+
auto log_handler = current_log_record_handler;
51+
if( log_handler )
52+
{
53+
(*log_handler)( log );
54+
}
55+
}
56+
57+
58+
}}
+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
// Copyright (c) 2012 A. Joel Lamotte <[email protected]>.
2+
// Distributed under the Boost Software License, Version 1.0.
3+
// (See accompanying file LICENSE_1_0.txt or copy at
4+
// http://www.boost.org/LICENSE_1_0.txt)
5+
6+
#ifndef NETWORK_LOGGING_HPP_20121112
7+
#define NETWORK_LOGGING_HPP_20121112
8+
9+
#include <sstream>
10+
#include <functional>
11+
12+
namespace network { namespace logging {
13+
14+
class log_record;
15+
16+
//using log_record_handler = std::function< void (const std::string&) >; // use this when VS can compile it...
17+
typedef std::function< void (const log_record&) > log_record_handler;
18+
19+
void set_log_record_handler( log_record_handler handler );
20+
void log( const log_record& message );
21+
22+
namespace handler
23+
{
24+
log_record_handler get_std_log_handler();
25+
log_record_handler get_default_log_handler();
26+
}
27+
28+
/** Helper to build a log record as a stream. */
29+
class log_record
30+
{
31+
public:
32+
log_record()
33+
: m_filename( UNKNOWN_FILE_NAME )
34+
, m_line(0)
35+
{} // = default;
36+
37+
static const char* UNKNOWN_FILE_NAME;
38+
39+
// Implicit construction from anything serializable to text.
40+
template< typename TypeOfSomething >
41+
log_record( TypeOfSomething&& message )
42+
: m_filename( UNKNOWN_FILE_NAME )
43+
, m_line(0)
44+
{
45+
write( std::forward<TypeOfSomething>(message) );
46+
}
47+
48+
// Construction with recording context informations.
49+
log_record( std::string filename, unsigned long line )
50+
: m_filename( filename )
51+
, m_line( line )
52+
{
53+
}
54+
55+
template< typename TypeOfSomething >
56+
log_record& write( TypeOfSomething&& something )
57+
{
58+
m_text_stream << something;
59+
return *this;
60+
}
61+
62+
template< typename TypeOfSomething >
63+
inline log_record& operator<<( TypeOfSomething&& something )
64+
{
65+
return write( std::forward<TypeOfSomething>(something) );
66+
}
67+
68+
std::string message() const { return m_text_stream.str(); }
69+
const std::string& filename() const { return m_filename; }
70+
unsigned long line() const { return m_line; }
71+
72+
private:
73+
74+
// disable copy
75+
log_record( const log_record& ); // = delete;
76+
log_record& operator=( const log_record& ); // = delete;
77+
78+
std::ostringstream m_text_stream; // stream in which we build the message
79+
std::string m_filename; // = UNKNOWN_FILE_NAME;
80+
unsigned long m_line; // = 0;
81+
};
82+
83+
}}
84+
85+
86+
#endif /* end of include guard: NETWORK_LOGGING_HPP_20121112 */

logging/test/CMakeLists.txt

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Copyright (c) A. Joel Lamotte 2012.
2+
# Distributed under the Boost Software License, Version 1.0.
3+
# (See accompanying file LICENSE_1_0.txt or copy at
4+
# http://www.boost.org/LICENSE_1_0.txt)
5+
6+
include_directories(${CPP-NETLIB_SOURCE_DIR}/include)
7+
include_directories(${CPP-NETLIB_SOURCE_DIR})
8+
9+
if (Boost_FOUND)
10+
set(
11+
TESTS
12+
logging_log_record
13+
logging_custom_handler
14+
)
15+
foreach (test ${TESTS})
16+
if (${CMAKE_CXX_COMPILER_ID} MATCHES GNU)
17+
set_source_files_properties(${test}.cpp
18+
PROPERTIES COMPILE_FLAGS "-Wall")
19+
endif()
20+
add_executable(cpp-netlib-${test} ${test}.cpp)
21+
add_dependencies(cpp-netlib-${test} cppnetlib-logging)
22+
target_link_libraries(cpp-netlib-${test}
23+
${Boost_LIBRARIES} cppnetlib-logging)
24+
set_target_properties(cpp-netlib-${test}
25+
PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CPP-NETLIB_BINARY_DIR}/tests)
26+
add_test(cpp-netlib-${test}
27+
${CPP-NETLIB_BINARY_DIR}/tests/cpp-netlib-${test})
28+
endforeach (test)
29+
endif()
+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Copyright (c) 2012 A. Joel Lamotte <[email protected]>
2+
// Distributed under the Boost Software License, Version 1.0.
3+
// (See accompanying file LICENSE_1_0.txt or copy at
4+
// http://www.boost.org/LICENSE_1_0.txt)
5+
6+
#include <string>
7+
#include <sstream>
8+
9+
#define BOOST_TEST_MODULE logging log_record
10+
#include <boost/config/warning_disable.hpp>
11+
#include <boost/test/unit_test.hpp>
12+
13+
#include <network/logging/logging.hpp>
14+
15+
using namespace network::logging;
16+
17+
BOOST_AUTO_TEST_CASE(custom_log_handler_output) {
18+
19+
std::stringstream log_output;
20+
auto custom_log_handler = [&]( const log_record& log )
21+
{
22+
log_output << "[CPPNETLIB]<" << log.filename() << ":" << log.line() << "> "
23+
<< log.message();
24+
};
25+
26+
const auto line_num = 42;
27+
const auto file_name = "somewhere.cpp";
28+
const auto message = "At line " + std::to_string(line_num) + " we check the code.";
29+
30+
set_log_record_handler( custom_log_handler );
31+
log( log_record( file_name, line_num ) << "At line " << line_num << " we check the code." );
32+
33+
const auto result_output = log_output.str();
34+
35+
BOOST_CHECK( !result_output.empty() );
36+
BOOST_CHECK( result_output == "[CPPNETLIB]<somewhere.cpp:42> " + message );
37+
}

logging/test/logging_log_record.cpp

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// Copyright (c) 2012 A. Joel Lamotte <[email protected]>
2+
// Distributed under the Boost Software License, Version 1.0.
3+
// (See accompanying file LICENSE_1_0.txt or copy at
4+
// http://www.boost.org/LICENSE_1_0.txt)
5+
6+
#include <string>
7+
8+
#define BOOST_TEST_MODULE logging log_record
9+
#include <boost/config/warning_disable.hpp>
10+
#include <boost/test/unit_test.hpp>
11+
12+
#include <network/logging/logging.hpp>
13+
#define NETWORK_ENABLE_LOGGING
14+
#include <network/detail/debug.hpp>
15+
16+
using namespace network::logging;
17+
18+
BOOST_AUTO_TEST_CASE(default_constructor) {
19+
log_record record;
20+
BOOST_CHECK( record.message() == "" );
21+
BOOST_CHECK( record.filename() == log_record::UNKNOWN_FILE_NAME );
22+
BOOST_CHECK( record.line() == 0 );
23+
}
24+
25+
BOOST_AUTO_TEST_CASE(cstring_constructor) {
26+
const auto message = "This is a test.";
27+
log_record record( message );
28+
BOOST_CHECK( record.message() == message );
29+
BOOST_CHECK( record.filename() == log_record::UNKNOWN_FILE_NAME );
30+
BOOST_CHECK( record.line() == 0 );
31+
}
32+
33+
BOOST_AUTO_TEST_CASE(string_constructor) {
34+
const std::string message("This is a test.");
35+
log_record record( message );
36+
BOOST_CHECK( record.message() == message );
37+
BOOST_CHECK( record.filename() == log_record::UNKNOWN_FILE_NAME );
38+
BOOST_CHECK( record.line() == 0 );
39+
}
40+
41+
BOOST_AUTO_TEST_CASE(int_constructor) {
42+
const auto num = 42;
43+
log_record record( num );
44+
BOOST_CHECK( record.message() == std::to_string( num ) );
45+
BOOST_CHECK( record.filename() == log_record::UNKNOWN_FILE_NAME );
46+
BOOST_CHECK( record.line() == 0 );
47+
}
48+
49+
BOOST_AUTO_TEST_CASE(info_constructor) {
50+
const auto line_num = 42;
51+
const auto file_name = "somewhere.cpp";
52+
log_record record( file_name, line_num );
53+
BOOST_CHECK( record.message() == "" );
54+
BOOST_CHECK( record.filename() == file_name );
55+
BOOST_CHECK( record.line() == line_num );
56+
}
57+
58+
BOOST_AUTO_TEST_CASE(text_stream) {
59+
const auto line_num = 42;
60+
const auto file_name = "somewhere.cpp";
61+
const auto message = "At line " + std::to_string(line_num) + " we check the code.";
62+
log_record record( file_name, line_num );
63+
64+
record << "At line " << line_num << " we check the code.";
65+
66+
BOOST_CHECK( record.message() == message );
67+
BOOST_CHECK( record.filename() == file_name );
68+
BOOST_CHECK( record.line() == line_num );
69+
}
70+
71+
BOOST_AUTO_TEST_CASE(raw_log) {
72+
log( "This is a raw log." );
73+
}
74+
75+
BOOST_AUTO_TEST_CASE(macro_log) {
76+
NETWORK_MESSAGE( "This is a log through the macro." );
77+
NETWORK_MESSAGE( "This is a log through the macro, with a stream! Num=" << 42 << " - OK!" );
78+
}

0 commit comments

Comments
 (0)