Ok, thank you for the input.
A special macro or function seems like the right way to go. Terminating from within the library will not guarantee that all log records are processed. Also, calling core::flush() from an atexit handler won't work because the library is likely terminated at this stage.
Hi, yes, I agree the library should not terminate but I was wondering if you had a suggestion on the best way to implement the termination. We have tried a callback to std::terminatewith a call to core::flush() and nothing is output to the logs. We have done this with special macro for the fatal severity. We would prefer to not have a special macro. I thought you might have a suggestion on the best way to implement such a feature using features of the library. Thanks
It's not the logging library's job to terminate the application. If you want to terminate then go ahead and do that - in the application. You may want to call core::flush() to make sure all log records are processed.
Well, for one thing the program keeps running. :-) We would like FATAL to call abort or terminate after the log message is written and all the log messages are flushed. Unless we missed something, the log library does not do this for you.
What's wrong with BOOST_LOG_SEV(lg, fatal) << "Good bye cruel world"?
Hi, I was wondering if you have any suggestions on how to correctly implement a fatal log message using the multi-threaded severity logger without creating a special macro for the FATAL condition. Thank you.
Thank you. That does solve the issue.
You need to build Boost with TSan as well. And using clang-14. Add -fsanitize=thread to cxxflags and linkflags and add toolset=clang-14 in b2 command line.
Continuation of thread: https://sourceforge.net/p/boost-log/discussion/710022/thread/555365ac/?limit=25 Compiled boost 1.80 library using gcc: gcc --version gcc (Ubuntu 11.2.0-19ubuntu1) 11.2.0 ./bootstrap.sh sudo ./b2 release link=shared cxxflags=-fPIC cflags=-fPIC -a install Modified boost_1_77_0/libs/log/example/advanced_usage/main.cpp to have some threads. See attached file. Compiled with using thread sanitizer: Ubuntu clang version 14.0.6-++20220622053133+f28c006a5895-1~exp1~20220622173215.107...
Did you build Boost with TSan? What compiler flags did you use? What exact source code, with everything irrelevant removed, reproduces it? Please post in another thread.
Did you build Boost with TSan? What compiler flags did you use? Please post in another thread.
Sorry about the off topic post, but it did relate to an earlier post about using the wrap_formatter and getting a race condition. I upgraded to 1.80 and still can reproduce the data race using log/example/advanced_usage/main.cpp with some minor modifications described above.
I also had to change slg to severity_logger_mt. I cannot reproduce this on the current develop branch on my Ubuntu 22.04 and clang 14. Also, please don't post off-topic in this thread. This discussion is about __FILE__ and __LINE__ formatting.
I also had to change slg to severity_logger_mt. I cannot reproduce this on the current develop branch on my Ubuntu 22.04 and clang 14.
Hi, to show the data race I modified the following example program: boost_1_77_0/libs/log/example/advanced_usage/main.cpp I added the following functions: void f1(int n, src::severity_logger_mt<severity_level>& slg) { for (int i = 0; i < 25; ++i) { BOOST_LOG_SEV(slg, error) << "Thread 1 executing " << i; ++n; std::this_thread::sleep_for(std::chrono::milliseconds(10)); } } void f2(int& n, src::severity_logger_mt<severity_level>& slg) { BOOST_LOG_SCOPED_LOGGER_TAG(slg, "Tag", "Tagged f2 "); for (int...
Do not initialize anything but the logger itself in the global logger initializer. It is not guaranteed that the initializer is only run once.
I'm wondering if we do not have the logger setup correctly to support a multithreaded environment. Logging.hpp: BOOST_LOG_GLOBAL_LOGGER(boostLogger, boost::log::sources::severity_logger_mt<LogSeverity>) Logging.cpp: BOOST_LOG_GLOBAL_LOGGER_INIT(boostLogger, boost::log::sources::severity_logger_mt<LogSeverity>) { using LoggerType = boost::log::sources::severity_logger_mt<LogSeverity>; LoggerType logger; boost::log::add_file_log( keywords::file_name = fileName, keywords::auto_flush = true, keywords::open_mode...
The test is multi-threaded but it does not use any of the BOOST macros in any of the threads except the main thread. AFAIK it is the BOOST macros that are not thread safe. Only calls to BOOST_LOG_SCOPED_LOGGER_TAG and BOOST_LOG_SEV(logger, severity) << msg are made in the threads. It's the call to expr::stream << expr::attr< std::string >("Tag") that causes the data race. I don't see how the code could be destroying the Tag attribute while some place else is updating it. The Tag attribute for this...
I just noticed that the backtrace mentions Boost.Test. AFAIK, Boost.Test is not thread-safe, it should not be used from multiple threads.
This is off-topic but BOOST_LOG_SCOPED_LOGGER_TAG does not introduce a data race if used with a multi-threaded logger. The backtrace makes no sense to me as Boost.Log doesn't use Boost.Function. Looks like TSan is triggering a race on the virtual function table pointer. This can happen if your code is destroying the attribute while a method is being called on it.
This is off-topic but BOOST_LOG_SCOPED_LOGGER_TAG does not introduce a data race if used with a multi-threaded logger. The backtrace makes no sense to me as Boost.Log doesn't use Boost.Function. Looks like TSan is falsely triggering a race on the virtual function table pointer.
Thank you. I missed that post and option 3. I do have a concern about using BOOST_LOG_SCOPED_LOGGER_ATTR. I currently use this for setting a TAG field but get get thread sanitizer data race errors. I'm using "boost::log::sources::severity_logger_mt<>". I do the following in a few different places. BOOST_LOG_SCOPED_LOGGER_TAG(lg, "Tag", "some-tag-message"); I then run a multi-threaded test program using the clang thread sanitizer and get a data race on the Tag output. expr::stream << expr::format_date_time<...
I answered it here. Since you need filtering, option 3 fits your case. One other option is to define a new logger feature that will manage the file and line attributes. This would have better performance since the attributes wouldn't be added/removed on every log record. But this would still require defining a new logging macro since this is the only way to use __FILE__ and __LINE__ macros. You can read about creating logger features here.
Ok, I thought it was going to be a bad idea. Do you have a suggestion on how to get FILE for every place the logger is called, so it can participate in filtering? For every "BOOST_LOG_SEV(logger, severity) << msg;" statement in the code we need FILE so we can filter on filename and severity. This needs to be the exact location of the log message so scoping variables will not work. This is an ongoing question for the logger that no one seems to have a good solution for. Any help is greatly apprec...
I don't think this is a good idea because you are copying thread-specific attributes and searching for the attribute - twice - per every log record being made. Copying an attribute set involves one or more memory allocations, depending on the number of attributes. Furthermore, passing the result of set_get_attrib to BOOST_LOG_STREAM_WITH_PARAMS is not intended to work. The list is supposed to be a list of named parameters that is composed onto named parameters pack that is then consumed by open_record...
Andrey, can I get your opinion on a post I saw. Is this an OK idea or a bad idea. It's along the lines of this conversation of how to get file information into the log and it needs to be available for filtering records to boost::log::add_value will not work. From post: https://stackoverflow.com/questions/24750218/boost-log-to-print-source-code-file-name-and-line-number // New macro that includes severity, filename and line number #define CUSTOM_LOG(logger, sev) \ BOOST_LOG_STREAM_WITH_PARAMS( \ (logger),...
Hi, is using the expr::wrap_formatter in multi-threaded log (boost::log::sources::severity_logger_mt) thread safe? Yes, meaning that wrap_formatter itself does not introduce data races as it doesn't modify any shared data. The wrapped function though is not protected from concurrent calls.
Hi, is using the expr::wrap_formatter in multi-threaded log (boost::log::sources::severity_logger_mt) thread safe? I am running the clang thread sanitizer (https://clang.llvm.org/docs/ThreadSanitizer.html) and getting many data race conditions reported. Thanks
What is the proper way to destruct a global logger? There isn't one. Global loggers are destroyed when global destructors are called. Valgrind generates its report at this stage too, which is why it may list those allocations. Ignore those records.
What is the proper way to destruct a global logger? We get valgrind errors on program termination. ==330953== 16 bytes in 1 blocks are still reachable in loss record 3 of 6 ==330953== at 0x48468D5: operator new(unsigned long) (vg_replace_malloc.c:422) ==330953== by 0x4EE0923: boost::detail::add_thread_exit_function(boost::detail::thread_exit_function_base*) (in /usr/local/lib/libboost_thread.so.1.77.0) ==330953== by 0x4D80306: boost::log::v2_mt_posix::sources::aux::get_severity_level() (in /usr/local/lib/libboost_log.so.1.77.0)...
Thank you. I was able to get the expr::wrap_formatter to work.
First, you don't derive from basic_formatter. It is not a base class but a wrapper that erases the type of the actual formatter, a-la std::function with a fixed signature. Next, there are multiple ways to integrate with formatting expressions, but ultimately what you need to do is to turn your formatter function into a Boost.Phoenix terminal. One easy way to do this is to use wrap_formatter: template<typename CharT> class SuperCustomFormatter { public: //! Formatter character type. This will help...
Is it possible to get a working solution posted for this question? I have a similar issue and cannot get the formatter to compile when used as an expression. template<typename CharT> class SuperCustomFormatter : public boost::log::formatter::basic_formatter<CharT> { public: explicit SuperCustomFormatter(boost::log::attribute_name const& name) : name(name) {} void operator()(boost::log::formatting_ostream& strm, boost::log::value_ref< SuperCustomObject > const& value) const { if (value) { format(strm);...
That is just a keyword which is used to refer to attribute values, it does not define an attribute. There are two attributes you can use to generate timestamps: local_clock and utc_clock. If you add the latter, you get UTC time readings.
The example is given in the linked page, just replace attrs::local_clock with attrs::utc_clock.
Hello, can you provide an example?
Thanks a lot for your answer!
There are no built-in filters for named scopes, neither in the programming API nor in the settings files. Named scopes were mostly designed as a means of aiding diagnostics rather than filtering log records. That's why there is a dedicated formatter for named scopes. However, you could implement the filter yourself, as described in the SO question. Then, you can create a filter factory and register it in the library for a specific attribute, as described here. The filter factory will be invoked by...
Hello, I'd like to ask you for advice. Is there a way how to configure a filter by named scope in a configuration file (loaded by init_from_stream)? Filter="%Scope% contains \"Dwg\"" doesn't work for me (when used, no records are written to the result log file - the sink I use). Should it work or shall I use a different way? Whereas Format="%LineID%#%TimeStamp%#%Severity%#%Scope%#%Message%" works well. I guess it's because Scope isn't a string attribute but a special type with the stack and stuff...
Please post a full compilable code sample. Also, use code formatting so it is easier to read and not mangled by the text formatting.
This is the example being followed : BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", severity_level) BOOST_LOG_ATTRIBUTE_KEYWORD(channel, "Channel", std::string) logging::add_file_log( keywords::file_name = "A.log", keywords::filter = channel == "A"); logging::add_file_log( keywords::file_name = "B.log", keywords::filter = channel == "B"); typedef src::severity_channel_logger< severity_level, std::string > logger_type; logger_type lg_a(keywords::channel = "A"); logger_type lg_b(keywords::channel...
Still compiles fine. Check your build environment and Boost integrity. Maybe your build system mixes up headers from different Boost versions or something.
Boost version : 1.72.0 compiler : gcc - version 9.3.0
That example compiles without errors on my system with gcc 10 in C++11 mode. C++11 is not a compiler, it's C++ standard version. What is your compiler and what Boost.Log version?
I am using this example https://www.boost.org/doc/libs/1_60_0/libs/log/example/doc/expressions_channel_severity_filter.cpp compiler is c++11
Can you provide a complete compilable code sample that reproduces the problem. Also, what compiler are you using?
Below line is gving the error: BOOST_LOG_ATTRIBUTE_KEYWORD(a_channel,"Channel", std::string) Error : error: template argument 1 is invalid typedef ::boost::log::expressions::attribute_keyword< tag_ns_::keyword_ > BOOST_PP_CAT(keyword_, _type);
When you haven't written any log records, and there wasn't a previous log file with a name matching the filename pattern you set, there isn't any log file (i.e. it's not an empty file, but there is no file at all). In that case rotating the file manually will throw, indicating a failure. It is up to you how to deal with that exception. You can ignore it if you want to.
i try to manually rotate file but error happens if file is empty.can i rotate empty file"with no logs". the error is related to file system not finding path.and i find file name =0000 although i give back end certain target file name. what can i do?
Thank you very much for your quick answer, it works now! I missed that part when I was looking at how to implement sinks.
Some attributes, including severity level, are implemented using thread-specific data. When log records containing values of such attributes cross thread boundaries, these values need to be copied into thread-independent memory. This is done automatically by the logging core, if a sink indicates that it will require thread-independent log records by returning true from sink::is_cross_thread. For this to happen, the derived sink frontend must provide true to the sink constructor.
Forgot... I also tested: record_view copy construction passing record_view to a lambda and firing it right away in both cases the severity attribute is copied correctly.
Hi, I'm trying to write my own sink frontend that uses tasks (libdispatch) for feeding records. I'm experiencing some strange behaviour with the severity attribute. I extended the severity levels with my own enum class (adding a few more). I was previously using the async frontend and everything was working fine. To start the implementation of the new frontend I took the unlocked sink from the boost sources as a reference. The problem is in consume, which looks like this: void consume(record_view...
Hi, I'm trying to write my own sink frontend that uses tasks (libdispatch) for feeding records. I'm experiencing some strange behaviour with the severity attribute. I extended the severity levels with my own enum class (adding a few more). I was previously using the async frontend and everything was working fine. To start the implementation of the new frontend I took the unlocked sink from the boost sources as a reference. The problem is in consume, which looks like this: void consume(record_view...
Thanks Andrey! I'll try that :)
You're not setting the target directory for collected log files (i.e. the target named parameter is missing). max_files limits the number of collected files, so it has no effect when collecting is not enabled.
Hi, I have the following code: void init_logger(const std::string &logfile, boost::log::trivial::severity_level loglevel) { boost::log::add_file_log(boost::log::keywords::file_name = logfile + ".%N", boost::log::keywords::time_based_rotation = boost::log::sinks::file::rotation_at_time_point(0, 0, 0), boost::log::keywords::open_mode = std::ios_base::app, boost::log::keywords::max_files = 10, boost::log::keywords::rotation_size = 5 * 1024 * 1024, boost::log::keywords::auto_flush = true, boost::log::keywords::format...
Destructors are not required to be called if the exception is not caught. The language runtime can simply terminate the program without stack unwinding. Also, this forum is not the place for general C++ questions. Try StackOverflow instead.
Hi, I was going through Dimitri Reiswich slides on Boost posted in Quantlib.org and when trying to replicate his examples noted that after throwing an exception the destructor is not called even though I am using shared_ptr. When calling the below function I should get: Constructor of A Destructor of A with value 1 Error ocurred in testSharedPtr However I get error message as below. Does anyone know why is this happening? Code, as per the slides is below. I’m using VS2010. Thanks in advance, Debug...
too long file name is the problem ....it is problem of boost file system on windows
hi i try in short to flush then rotate file to keep log file for each folder then i try to change name of log file this is part of code: BNBSPiter2 is iterator to boost::bimap of backend name string and shared pointer to the back end BackendFileName is string representing file name for log without any pattern"i wonder if set_file_name_pattern can change file name without certain pattern " //i wanna flush rotate and change filename in backend shared pointer std::string BackendCurrentFileName = BNBSPiter2->second->get_current_file_name().filename().generic_string();...
Regarding the linking problem, I think this is some sort of configuration problem or misuse. Make sure that (1) you actually link with the object file that contains BOOST_LOG_GLOBAL_LOGGER_INIT definition, (2) compiler options for all files, including macros, are the same, (3) the logger name and type in BOOST_LOG_GLOBAL_LOGGER and BOOST_LOG_GLOBAL_LOGGER_INIT are the same, (4) both macros are used in the same namespace and (5) there are no multiple BOOST_LOG_GLOBAL_LOGGER with the same logger name....
Regarding the linking problem, I think this is some sort of configuration problem or misuse. Make sure that (1) you actually link with the object file that contains BOOST_LOG_GLOBAL_LOGGER_INIT definition, (2) compiler options for all files, including macros, are the same, (3) the logger name and type in BOOST_LOG_GLOBAL_LOGGER and BOOST_LOG_GLOBAL_LOGGER_INIT are the same, (4) both macros are used in the same namespace and (5) there are no multiple BOOST_LOG_GLOBAL_LOGGER with the same logger name....
Thank you very much. I will look into that section you provided. Really appreciate your help on custom attributes. On the linking, it is strange, may be something to do with my VS2015, it complains about C++14 as well. I will get latest update and try again. Thanks again!
I can't reproduce the problem with BOOST_LOG_GLOBAL_LOGGER_INIT. The following code compiles, links and runs for me: // global_logger.h #include <boost/log/common.hpp> namespace src = boost::log::sources; BOOST_LOG_GLOBAL_LOGGER(my_logger, src::severity_logger_mt< >) // global_logger_init.cpp #include <boost/log/attributes/timer.hpp> #include "global_logger.h" namespace attrs = boost::log::attributes; BOOST_LOG_GLOBAL_LOGGER_INIT(my_logger, src::severity_logger_mt< >) { src::severity_logger_mt< >...
I am particularly looking to know if I can add custom paramters and use parse_settings to get it and use them in the ilter for scope filtering via configuration file. I would really appreciate if you could point me to something. thanks again.
Hi Andrey, thanks for reply. Yes. I have implemented logger initialization something similiar to this. But somehow it fails to link with driver program. / my_logger.h // =========== BOOST_LOG_GLOBAL_LOGGER(my_logger, src::severity_logger_mt) // my_logger.cpp // =========== include "my_logger.h" BOOST_LOG_GLOBAL_LOGGER_INIT(my_logger, src::severity_logger_mt) { src::severity_logger_mt< > lg; lg.add_attribute("StopWatch", boost::make_shared< attrs::timer >()); return lg; } I have been able to resolve...
I was able to resolve #4 , by linking with psapi.lib. Perhaps, it depends on this for windows env only.
Did you actually implement the body of the logger initialization after the BOOST_LOG_GLOBAL_LOGGER_INIT macro? See the example in the docs. What you see in logs is defined exclusively by the formatter that you set by calling set_formatter. Any attributes that you add, including via the add_value manipulator, are simply ignored unless they are used somewhere down the processing pipeline, primarilly in a filter or formatter. If you want to add more data to the log, you have to write the formatter so...
it was bimap issue sorry
on #1, when I use BOOST_LOG_GLOBAL_LOGGER in logger.hpp and BOOST_LOG_GLOBAL_LOGGER_INIT in logger.cpp , I am getting the following linker error in the driver program(hello_test.cpp): hello_test.obj error LNK2001 unresolved external symbol "public static class: boost::log::v2s_mt_nt6::sources::severity_channel_mt<enum boost::log::v2s_mt_nt6::trivial::severity_level,="" class="" std::basic_string<char,="" std::char_traits<="" char="">, std::allocator<char>> > __cdecl mynamespace::construct_logger(void)"...
I was able to resolve the scope filtering issue. Thank you so much for your help!
When I use BOOST_LOG_GLOBAL_LOGGER in hpp and BOOST_LOG_GLOBAL_LOGGER_INIT in.cin.cpp I get linker error on construct_logger(void) . It does not recognize the symbol. I cant post from work anymore will type complete signature shortly.Tshortly.Thasks for reply
What linker errors? Note that you have to use BOOST_LOG_GLOBAL_LOGGER_INIT, BOOST_LOG_GLOBAL_LOGGER_DEFAULT and BOOST_LOG_GLOBAL_LOGGER_CTOR_ARGS in a single transpation unit (i.e. a single .cpp) while BOOST_LOG_GLOBAL_LOGGER can be visible in many (i.e. can be in a header). I don't understand the question, sorry. Could you describe what you're trying to do? Filtering by named scopes is possible, but you will have to write the filter yourself. The library does not offer any specialized filters for...
1.66 Boost version on MSVC 2015- forgot to add this.
Hi I am tring to use boost log for my project and facing difficulty with following: 1. unable to use BOOST_LOGGLOBAL_LOGGER/BOOST_LOG_GLOBAL_LOGGER_INIT havint o use BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT to get rid of linker error 2. BOOST_LOG_SEV(my_logger::get(), boost::log::trivial::trace) \ << logging::add_value("RecordLine", LINE__) \ << logging::add_value("CurrentFunction", BOOST_CURRENT_FUNCTION) vs set_format. Only can see everything in set_format nothing above. which takes precedence? is...
hi i made this logging class to allow me to build loggers during the program working then use them this is the class: my_logger_class_4.h #ifndef MY_LOGGER_CLASS_3_H // if my_logger.h hasn't been included yet... #define MY_LOGGER_CLASS_3_H // #define this so the compiler knows it has been included #include <boost/log/sinks/sync_frontend.hpp> #include <boost/log/sinks/text_file_backend.hpp> //for cout logger #include <boost/log/sinks/text_ostream_backend.hpp> #include <boost/core/null_deleter.hpp>...
hi i made this logging class to allow me to build loggers during the program working then use them this is the class: my_logger_class_4.h //#pragma once #ifndef MY_LOGGER_CLASS_3_H // if my_logger.h hasn't been included yet... #define MY_LOGGER_CLASS_3_H // #define this so the compiler knows it has been included /* 0-first date with 404 1-first date with 200 2-dates with zero size after first date with 200 3-dates of saturday and sunday after first date with 200 4-dates not saturday or sunday after...
You can use formatters with the syslog sink backend, like with other text-based sinks. In order to be able to insert pid into the message, you will have to addit as an attribute first. An example of formatting pid into log messages is available here.
Hi I am using boost.log for the logging in my application and the messages are sent with rsyslog. I want to insert the process ID into my log messages and so I tried to insert it in the syslog template with "property(name="procid")" but the field is empty. Is there any possibility to set the field with the boost logging lib? Or is there a another workaround to handle the problem?! best regards Harald
Even if implemented the same way, int and long are distinct types. Note that the C++ standard doesn't mandate the exact type of the constant produced by __LINE__, so you might want to add an explicit cast to some specific integer type.
Using VisualStudio 2017 (15.6.4). When compiling in x64: #define MY_LOG(_log, _sev) BOOST_LOG_SEV( _log, _sev) \ << boost::log::add_value("SrcLine", __LINE__) \ << boost::log::add_value("SrcFile", __FILE__) the following doesn't work: strm << boost::log::extract< int >("SrcLine", rec) << ": "; boost::log::value_ref< std::string > fullpath = boost::log::extract< std::string >("SrcFile", rec); strm << boost::filesystem::path(fullpath.get()).filename().string() << ": "; while the following works: strm...
Using VisualStudio 2017 (15.6.4). When compiling in x64: #define MY_LOG(_log, _sev) BOOST_LOG_SEV( _log, _sev) \ << boost::log::add_value("SrcLine", __LINE__) \ << boost::log::add_value("SrcFile", __FILE__) the following doesn't work: strm << boost::log::extract< int >("SrcLine", rec) << ": "; boost::log::value_ref< std::string > fullpath = boost::log::extract< std::string >("SrcFile", rec); strm << boost::filesystem::path(fullpath.get()).filename().string() << ": "; while the following works: strm...
I couldn't find what they said in 1.63,Maybe modified branches/release/boost/thread/win32/thread_primitives.hpp if _WIN32_WINNT >= 0x0600 && ! defined _WIN32_WINNT_WS08 define BOOST_THREAD_WIN32_HAS_GET_TICK_COUNT_64
I couldn't find what they said in 1.63,Maybe modified branches/release/boost/thread/win32/thread_primitives.hpp if _WIN32_WINNT >= 0x0600 && ! defined _WIN32_WINNT_WS08 define BOOST_THREAD_WIN32_HAS_GET_TICK_COUNT_64
Thank you very much for your reply,I added #define _WIN32_WINNT 0x0501 to stdafx.h and it solved the problem,Reference: https://svn.boost.org/trac10/ticket/8070?cversion=1&cnum_hist=13
First, Windows XP is 0x501, 0x502 is Windows Server 2003. You may also need to select a special MSVC toolset to build for XP, see here for example: https://stackoverflow.com/questions/35664861/how-to-target-windows-xp-in-microsoft-visual-studio-c I'm not sure how to configure Boost.Build to use this toolset, though.
On March 7, 2018 4:16:48 AM "atu" zhangatu@users.sourceforge.net wrote: Direct download from the official website also installed the same result AFAIK, the pre-built binaries are compiled for the default Windows version, which is Vista.
I have compiled boost has joined define BOOST_USE_WINAPI_VERSION=0x502, "Unable to locate program input point SleepConditionVariableSRW at Kernel.dll" My boost version 1.63, Visual Studio 2015
Direct download from the official website also installed the same result
I have compiled boost has joined define BOOST_USE_WINAPI_VERSION=0x502, "Unable to locate program input point at Kernel.dll" My boost version 1.63, Visual Studio 2015
thank you for your reply i declared the as static and it worked fine i think the local scope of the other code of user pdlarue was the reason that her code worked my code is of global scope so it needs static or nameless namescope thanks again i ll now struggle to declare loggers within the function init_logging then use them from main it will be a challenge see you
boost::shared_ptr< sinks::text_file_backend > backend0; is both a declaration and a definition. The variable has external linkage by default, which means it should be defined in a single translation unit. Otherwise you get linker errors if the variable is defined in multiple translation units. General C++ questions like this are better asked somewhere else, like on StackOverflow. Some things may be already answered. For example, see here.
hi again wanna know if the following code in mylogger.h represent declaration or definition: // declare a backend boost::shared_ptr< sinks::text_file_backend > backend0; and this one in mylogger.cpp also delaration or definition // create a backend backend0 = boost::make_shared< sinks::text_file_backend >(keywords::file_name = "first_date_with_404.log"); because when i include my logger.h in mylogger_main.cpp it compiles without errors but the linker when linking mylogger_main.obj complaints that...
Make sure you're including your header in the source file. And I mean your header and not some other header in one of the include paths that happens to have the same name. You can do that by generating preprocessed output with your compiler.
hi i put the definitions in function in my_logger.cpp file and it gave no errors i think is dont understand header and source files enough thanks for your help
hi again i am trying here to adhere to header declaration source implementation behaviour to gain it as personal trait
thanks for your reply i know i am newbie but i did studied smart pointers and the way they are counted my problem is simpler: they say that assign= operator is making new shared pointer increasing count of pointers but reset takes ownership of pointer without making new one>>>>this is understand but in my code what i declare "backend0,core,sink0"in my_logger.h is not seen declared in my_logger.cpp my_logger.h // declare a backend boost::shared_ptr< sinks::text_file_backend > backend0; my_logger.cpp...
make_shared is another, more efficient way to create an object and a shared pointer to it. You may need to first learn how C++ smart pointers work first before learning Boost.Log. There are books on C++ and Boost.SmartPtr documentation may be helpful as well.