Jump to content

  • Log In with Google      Sign In   
  • Create Account

14 years ago on June 15th Gamedev.net was first launched! We want to thank all of you for being part of our community and hope the best years are ahead of us. Happy birthday Gamedev.net!

#ActualHodgman

Posted 19 June 2012 - 08:49 AM

The main logging object handles adding file, line, function info, process and thread IDs, timestamps, possibly even call stacks when logging exceptions/errors, etc, to the message object

Do you need an object to do that? That's where the free-function comes in for me.

I prefer a single logging object with multiple logging channels, where each channel can be of a different type. i.e. a FileLoggingChannel for writing to file, a ConsoleLoggingChannel for writing to the console, a SocketLoggingChannel for sending the logs over the network to an external logging application/server. Each channel type just implements a simple interface

I'd prefer to avoid the uneccesary inheritance here and keep your different log back-ends decoupled:
class SocketLoggingChannel : NonCopyable

{

public:

  SocketLoggingChannel(...);

  ~SocketLoggingChannel();

  void log( const char* msg );

};



class ConsoleLoggingChannel: NonCopyable

{

public:

  ConsoleLoggingChannel(...);

  ~ConsoleLoggingChannel();

  void log( const char* msg );

};



cosnt char* FormatLogMessage(const char* fmt, ...);

typedef std::vector<std::function<void(const char*)>> ChannelVec;



#define Log(channels, fmt, ...) do {                        \

 cosnt char* msg = FormatLogMessage(fmt, __VA_ARGS__);      \

 for (auto &c : channels){                                  \

  c(msg);                                                   \

 }                                                          \

} while(0)                                                  //

#3Hodgman

Posted 19 June 2012 - 08:48 AM

The main logging object handles adding file, line, function info, process and thread IDs, timestamps, possibly even call stacks when logging exceptions/errors, etc, to the message object

Do you need an object to do that? That's where the free-function comes in for me.

I prefer a single logging object with multiple logging channels, where each channel can be of a different type. i.e. a FileLoggingChannel for writing to file, a ConsoleLoggingChannel for writing to the console, a SocketLoggingChannel for sending the logs over the network to an external logging application/server. Each channel type just implements a simple interface

I'd prefer to avoid the uneccesary inheritance here and keep your different log back-ends decoupled:
class SocketLoggingChannel : NonCopyable

{

public:

  SocketLoggingChannel(...);

  ~SocketLoggingChannel();

  void log( const char* msg );

};



class ConsoleLoggingChannel: NonCopyable

{

public:

  ConsoleLoggingChannel(...);

  ~ConsoleLoggingChannel();

  void log( const char* msg );

};



cosnt char* FormatLogMessage(const char* fmt, ...);

typedef std::vector<std::function<void(const char*)>> ChannelVec;



#define Log(channels, fmt, ...) do {						\

cosnt char* msg = FormatLogMessage(fmt, __VA_ARGS__);	  \

for (auto &c : channels){								  \

  c(msg);												   \

}														  \

} while(0)												  //

#2Hodgman

Posted 19 June 2012 - 08:47 AM

The main logging object handles adding file, line, function info, process and thread IDs, timestamps, possibly even call stacks when logging exceptions/errors, etc, to the message object

Do you need an object to do that? That's where the free-function comes in for me.

I prefer a single logging object with multiple logging channels, where each channel can be of a different type. i.e. a FileLoggingChannel for writing to file, a ConsoleLoggingChannel for writing to the console, a SocketLoggingChannel for sending the logs over the network to an external logging application/server. Each channel type just implements a simple interface

I'd prefer to avoid the uneccesary inheritance here and keep your different log back-ends decoupled:
class SocketLoggingChannel : NonCopyable

{

public:

  SocketLoggingChannel(...); 

  ~SocketLoggingChannel();

  void log( const char* msg );

};



class ConsoleLoggingChannel: NonCopyable

{

public:

  ConsoleLoggingChannel(...);

  ~ConsoleLoggingChannel();

  void log( const char* msg );

};



cosnt char* FormatLogMessage(const char* fmt, ...);

typedef std::vector<std::function<int(void*, const char*)>> ChannelVec;



#define Log(channels, fmt, ...) do {						\

 cosnt char* msg = FormatLogMessage(fmt, __VA_ARGS__);	  \

 for (auto &c : channels){								  \

  c(msg);												   \

 }														  \

} while(0)												  //

#1Hodgman

Posted 19 June 2012 - 08:46 AM

The main logging object handles adding file, line, function info, process and thread IDs, timestamps, possibly even call stacks when logging exceptions/errors, etc, to the message object

Do you need an object to do that? That's where the free-function comes in for me.

I prefer a single logging object with multiple logging channels, where each channel can be of a different type. i.e. a FileLoggingChannel for writing to file, a ConsoleLoggingChannel for writing to the console, a SocketLoggingChannel for sending the logs over the network to an external logging application/server. Each channel type just implements a simple interface

I'd prefer to avoid the uneccesary inheritance here and keep your different log back-ends decoupled:
class SocketLoggingChannel : NonCopyable

{

public:

SocketLoggingChannel();

~SocketLoggingChannel();

void log( const char* msg );

};



class ConsoleLoggingChannel

{

public:

ConsoleLoggingChannel();

~ConsoleLoggingChannel();

void log( const char* msg );

};



cosnt char* FormatLogMessage(const char* fmt, ...);

typedef std::vector<std::function<int(void*, const char*)>> ChannelVec;



#define Log(channels, fmt, ...) do {                        \

 cosnt char* msg = FormatLogMessage(fmt, __VA_ARGS__);      \

 for (auto &c : channels){                                  \

  c(msg);                                                   \

 }                                                          \

} while(0)                                                  //

PARTNERS