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

Added relay_sink. #3017

Closed
wants to merge 1 commit into from
Closed

Added relay_sink. #3017

wants to merge 1 commit into from

Conversation

risa2000
Copy link
Contributor

Adds relay_sink, which just wraps a full featured spdlog::logger.

This can be useful in an application which uses several standalone components (typically DLLs) where each instantiates its own logger to define an application specific log messages "routing".

For example, during an initialization of each DLL, the app can chose to replace the DLLs loggers' sinks with the relay_sink with its own global logger and thus rerouting all log messages from all loggers through its own sinks, without destroying the DLLs' loggers.

@gabime gabime closed this Jan 30, 2025
@risa2000
Copy link
Contributor Author

@gabime Hi there, any comment on closing this?

@gabime
Copy link
Owner

gabime commented Jan 30, 2025

I am trying not to insert new features in this branch. All new developments is in v2.x branch. Also in v2.x it might be not needed since the static state is much smaller(no registry) and dlls can just receive logger pointer to use.

@risa2000
Copy link
Contributor Author

Ah, ok on the frozen features.

FWIW The main reason for this was that typically my DLLs initialize their own logger at the startup (DLL_PROCESS_ATTACH) and the logger is shared internally in the implementation. I.e. I am not using one global logger, but each logical unit (instance, module) keeps its own logger reference. Depending on the complexity it may get referenced quite a few times before the DLL client gets a chance to do anything about it. So there is no easy way for the client to "replace" it once the references are spread.
But it can relatively easily replace the sinks of the logger.

@gabime
Copy link
Owner

gabime commented Jan 30, 2025

But it can relatively easily replace the sinks of the logger

logger->sinks() can be used to copy the sinks (not thread safe though, the sinks list should not be modified while the sink ptrs from sinks() are being copied)

@risa2000
Copy link
Contributor Author

I can copy sinks, and basically already use this, instead of just copying the sinks from the target logger to the DLL logger, I put the target logger in the relay sink and put this sink into the DLL logger. The idea behind is that the target logger controls now globally the log level and also can easily control which sinks it uses.

You can imagine an app which uses several DLLs, with this architecture, i.e. once the DLLs are loaded and initialized, the client app replaces all sinks in all DLLs with the relay_sink, rerouting all the logging to its own logger, and then the log level and the actual sinks it manages locally in the local logger. It is even easy to pass everything through a "filter" sink, which may filter log level based on source logger.

This has proven to be quite flexible and powerful architecture. Right now I need to subclass spdlog::logger in order to expose the protected log_it_ function so the relay_sink can use directly this when passing the log data to the wrapped logger. It is not a biggie, but having the support in the library will be definitely more elegant. (And the change as defined in this PR is rather trivial).

@risa2000
Copy link
Contributor Author

Following our conversation, I would like to say that what would be really helpful, if spdlog::logger interface has a public log_raw function which would allow logging the "native" details::log_msg, so the sink can directly pass its data to the logger.
I guess this is basically what this PR was about. relay_sink was just an application justifying this demand. But if you could just add log_raw to v2 it would be enough. Adding a relay_sink with log_raw support will be straightforward (and does not have to be in the library).

@gabime
Copy link
Owner

gabime commented Jan 31, 2025

Sure. PR is welcome. Should be very simple as it is just a wrapper around the sink_it_(..):

void log_raw(const &details::log_msg msg) noexcept {
    if (should_log(msg.log_level)) {
        sink_it_(msg);
     }
}

@risa2000
Copy link
Contributor Author

Great, should I submit it against v1, v2 or both?

@gabime
Copy link
Owner

gabime commented Jan 31, 2025

v2.x please

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

Successfully merging this pull request may close these issues.

2 participants