Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multisink with localisation #3305

Closed
WeleSS2 opened this issue Jan 1, 2025 · 4 comments
Closed

Multisink with localisation #3305

WeleSS2 opened this issue Jan 1, 2025 · 4 comments

Comments

@WeleSS2
Copy link

WeleSS2 commented Jan 1, 2025

Hello, i can't find discord or any other place where i can ask so i choose this place.

I created singleton where i'm keeping my sinks and logger, i want to display logs from code into files and console if console is enabled but i have 3 problems.

  1. Logs do not display even with flag in cmake (spdlog and nlohmann/json are incompatible ? #2764)
  2. I have build time error with trace as macro is trying to fit logger into log level?
  3. Logs are not saved to file though when file is opened
[build] C:\Repos\Cpp\CapibaraEngine\games\Fallen_Demon_Slayers\main.cpp(83,5): error C2665: 'spdlog::logger::log': no overloaded function could convert all the argument types [C:\Repos\Cpp\CapibaraEngine\build\games\Fallen_Demon_Slayers\Fallen_Demon_Slayers.vcxproj]
[build]       C:\Repos\Cpp\CapibaraEngine\build\_deps\spdlog-src\include\spdlog\logger.h(101,10):
[build]       could be 'void spdlog::logger::log(std::chrono::system_clock::time_point,spdlog::source_loc,spdlog::level::level_enum,spdlog::string_view_t)'
[build]           C:\Repos\Cpp\CapibaraEngine\games\Fallen_Demon_Slayers\main.cpp(83,5):
[build]           'void spdlog::logger::log(std::chrono::system_clock::time_point,spdlog::source_loc,spdlog::level::level_enum,spdlog::string_view_t)': cannot convert argument 1 from 'spdlog::source_loc' to 'std::chrono::system_clock::time_point'
[build]               C:\Repos\Cpp\CapibaraEngine\games\Fallen_Demon_Slayers\main.cpp(83,5):
[build]               No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
[build]       C:\Repos\Cpp\CapibaraEngine\build\_deps\spdlog-src\include\spdlog\logger.h(79,10):
[build]       or       'void spdlog::logger::log<const char(&)[23]>(spdlog::source_loc,spdlog::level::level_enum,std::basic_format_string<char,const char (&)[23]>,const char (&)[23])'
[build]           C:\Repos\Cpp\CapibaraEngine\games\Fallen_Demon_Slayers\main.cpp(83,5):
[build]           'void spdlog::logger::log<const char(&)[23]>(spdlog::source_loc,spdlog::level::level_enum,std::basic_format_string<char,const char (&)[23]>,const char (&)[23])': cannot convert argument 3 from 'spdlog::logger' to 'std::basic_format_string<char,const char (&)[23]>'
[build]               C:\Repos\Cpp\CapibaraEngine\games\Fallen_Demon_Slayers\main.cpp(83,5):
[build]               No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
[build]       C:\Repos\Cpp\CapibaraEngine\build\_deps\spdlog-src\include\spdlog\logger.h(97,10):
[build]       or       'void spdlog::logger::log(spdlog::source_loc,spdlog::level::level_enum,const T &)'
[build]           C:\Repos\Cpp\CapibaraEngine\games\Fallen_Demon_Slayers\main.cpp(83,5):
[build]           'void spdlog::logger::log(spdlog::source_loc,spdlog::level::level_enum,const T &)': expects 3 arguments - 4 provided
[build]       C:\Repos\Cpp\CapibaraEngine\build\_deps\spdlog-src\include\spdlog\logger.h(89,10):
[build]       or       'void spdlog::logger::log(spdlog::level::level_enum,const T &)'
[build]           C:\Repos\Cpp\CapibaraEngine\games\Fallen_Demon_Slayers\main.cpp(83,5):
[build]           'void spdlog::logger::log(spdlog::level::level_enum,const T &)': expects 2 arguments - 4 provided
[build]       C:\Repos\Cpp\CapibaraEngine\build\_deps\spdlog-src\include\spdlog\logger.h(84,10):
[build]       or       'void spdlog::logger::log(spdlog::level::level_enum,std::basic_format_string<char,type_identity<_Args>::type...>,Args ...)'
[build]           C:\Repos\Cpp\CapibaraEngine\games\Fallen_Demon_Slayers\main.cpp(83,5):
[build]           'initializing': cannot convert from 'spdlog::source_loc' to 'spdlog::level::level_enum'
[build]               C:\Repos\Cpp\CapibaraEngine\games\Fallen_Demon_Slayers\main.cpp(83,5):
[build]               No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
[build]       C:\Repos\Cpp\CapibaraEngine\games\Fallen_Demon_Slayers\main.cpp(83,5):
[build]       while trying to match the argument list '(spdlog::source_loc, spdlog::level::level_enum, spdlog::logger, const char [23])'

Basically all code which is involved is that:

int main() 
{
    std::cout << "Log 1" << std::endl;

    std::cout << "Log 2" << std::endl;
    
    SPDLOG_TRACE("Hello, {}!", "world");

    std::cout << "Log 3" << std::endl;

    std::cout << "Log 4" << std::endl;

    cLogs::getLogger()->info("Starting game...");

    std::cout << "Log 5" << std::endl;

    SPDLOG_TRACE(*cLogs::getLogger(), "Starting game MACRO...");

    std::cout << "Log 6" << std::endl;

...

class cLogs{
public:
    bool createLogger(bool consoleLogs = true);

    static spdlog::logger* getLogger() { return logger_; };
private:
    int logLevel_ = spdlog::level::off;

    std::string* currentPath_ = nullptr;

    std::shared_ptr<spdlog::sinks::stdout_color_sink_mt> consoleSink_;

    std::shared_ptr<spdlog::sinks::basic_file_sink_mt> fileSink_;

    static spdlog::logger *logger_;

...


bool cLogs::createLogger(bool consoleLogs)
{
    try
    {
        setCurrentPath("logs");
    
        if (consoleLogs)
        {
            consoleSink_ = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
        
            consoleSink_->set_pattern("[%T] [%@] %v");

            consoleSink_->set_level(spdlog::get_level());
        }

        fileSink_ = std::make_shared<spdlog::sinks::basic_file_sink_mt>(*currentPath_, true);

        fileSink_->set_pattern("[%T] [%@] %v");

        fileSink_->set_level(spdlog::get_level());

        if (consoleLogs)
        {
            logger_ = new spdlog::logger("logger", { consoleSink_, fileSink_ });    
        }
        else
        {
            logger_ = new spdlog::logger("logger", fileSink_);
        }

        return true;
    }
    catch (const spdlog::spdlog_ex& ex)
    {
        std::cout << "Log creation failed: " << ex.what() << std::endl;

        return false;
    }
}

I followed wiki and guides and in theory it should work but does not. Line with parsing logger throwing error, 1st log is not displayed or saved into file.

Output without parsing is
Log 1
Log 2
Log 3
...
Log 4
[2025-01-01 11:29:30.441] [logger] [info] Starting game...
Log 5
Log 6

So 1st log do not work when 2nd with parsing just give error.

@tt4g
Copy link
Contributor

tt4g commented Jan 1, 2025

The default value of the global log level is info, so spdlog::get_level() is also info. Trace level logs are not output as expected.

spdlog::level::level_enum global_log_level_ = level::info;

@WeleSS2
Copy link
Author

WeleSS2 commented Jan 1, 2025

The default value of the global log level is info, so spdlog::get_level() is also info. Trace level logs are not output as expected.

spdlog::level::level_enum global_log_level_ = level::info;

Yeah i was doing it but in wrong place... But still i do not understand why returning a pointer and dereferencing it then pushing to SPDLOG_TRACE give me error which i posted. I mean, i did exactly what was in wiki just wrapping it into static function from class and dereferenced pointer instead of direct object.

Im trying to make multisink logger for default logger with possibility to disable/enable console logs at compile time so i can have console logs when debugging some part and file always.

@tt4g
Copy link
Contributor

tt4g commented Jan 1, 2025

This is because the argument is wrong.
You cannot pass a logger to SPDLOG_TRACE. Use SPDLOG_LOGGER_TRACE instead.

-    SPDLOG_TRACE(*cLogs::getLogger(), "Starting game MACRO...");
+   SPDLOG_LOGGER_TRACE(*cLogs::getLogger(), "Starting game MACRO...");

#ifndef SPDLOG_NO_SOURCE_LOC
#define SPDLOG_LOGGER_CALL(logger, level, ...) \
(logger)->log(spdlog::source_loc{__FILE__, __LINE__, SPDLOG_FUNCTION}, level, __VA_ARGS__)
#else
#define SPDLOG_LOGGER_CALL(logger, level, ...) \
(logger)->log(spdlog::source_loc{}, level, __VA_ARGS__)
#endif
#if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_TRACE
#define SPDLOG_LOGGER_TRACE(logger, ...) \
SPDLOG_LOGGER_CALL(logger, spdlog::level::trace, __VA_ARGS__)
#define SPDLOG_TRACE(...) SPDLOG_LOGGER_TRACE(spdlog::default_logger_raw(), __VA_ARGS__)
#else
#define SPDLOG_LOGGER_TRACE(logger, ...) (void)0
#define SPDLOG_TRACE(...) (void)0
#endif

@WeleSS2
Copy link
Author

WeleSS2 commented Jan 3, 2025

I think i got it working, thanks

@WeleSS2 WeleSS2 closed this as completed Jan 3, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants