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

Support safe and unsafe logging modes as a workaround to formatting classes with mutable objects gotchas #20

Closed
odygrd opened this issue Apr 21, 2020 · 0 comments
Labels
enhancement New feature or request

Comments

@odygrd
Copy link
Owner

odygrd commented Apr 21, 2020

Currently Quill copies all user defined types and then formats them on a backend thread. This leads problems when user defined types include a mutable reference or pointer to another object.

I am thinking to have two modes available. It should be able to switch between them with a preprocessor definition.

Safe Logging

If this mode is used without providing a tag to all the safe objects it will degrade performance.
However, if used correctly it can achieve the same performance as unsafe logging in a safer way.

  • This mode will copy all safe to copy types that accepted by printf to the spsc queue and format them later on the backend logger thread.

  • For any user defined types check if copy_loggable_t tag is defined and copy the object without formatting, otherwise if the tag is not defined fallback to calling operator<< on the caller thread.

  • For all related stl objects and containers check the underlying type against 1) and 2) and decide whether to copy or format the container on the caller thread.

example :

class foo
{
    public:

      // Enables copying the object instead of formatting it in the caller thread. 
      // This object is safe to copy. But we are in SAFE_LOGGING and it would 
      // be formatted on the caller thread without this tag.

      using copy_loggable_t = std::true_type; 

      foo(int m) : mo(m) {};
      friend ostream& operator<<(ostream& os, const foo& f)
      {
          os << f.mo;
          return os;
      }

    int mo;
};

.

class foo
{
    public:

      // With SAFE_LOGGING this class will always be formatted by default 
      // on the caller thread and a string will be copied to the queue

      foo(int m) : mo(m) {};
      friend ostream& operator<<(ostream& os, const foo& f)
      {
          os << f.mo;
          return os;
      }

    int mo;
};

Unsafe Logging (Current Mode)

This mode will always attempt to copy all objects and format them in a backend logger thread.
The user has to be extra careful about objects that contain a mutable reference or a pointer as those members can change at any time :

  • after LOG_() was called but before formatting happened
  • during formatting
@odygrd odygrd added the enhancement New feature or request label Apr 21, 2020
@odygrd odygrd closed this as completed in ea739cd Apr 27, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant