Turning on verbose logging

3 minute readDeveloper productivity

Verbosity level is a way to control the verbosity of the SDK. By default, the verbosity level is set to silent. Sometimes, in order to troubleshoot things, we will want to turn on the verbosity.
To turn verbosity using the SDK, we need to change the verbosity level to debug.

React Native
JavaScript SSR
let options = ROXOptions() options.verbose = ROXOptionsVerboseLevelDebug ROX.setup(withKey:ROLLOUT_KEY, options:options) let allPaths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) let documentsDirectory = allPaths.first! let pathForLog = documentsDirectory.stringByAppendingString("/yourFile.txt") freopen(pathForLog.cStringUsingEncoding(NSASCIIStringEncoding)!, "a+", stderr)
ROXOptions *options = [[ROXOptions alloc] init]; options.verbose = ROXOptionsVerboseLevelDebug; [ROX setupWithKey:@"ROLLOUT_KEY" options: options]; NSArray *allPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [allPaths objectAtIndex:0]; NSString *pathForLog = [documentsDirectory stringByAppendingPathComponent:@"yourFile.txt"]; freopen([pathForLog cStringUsingEncoding:NSASCIIStringEncoding],"a+",stderr);
RoxOptions options = new RoxOptions.Builder() .withVerboseLevel(RoxOptions.VerboseLevel.VERBOSE_LEVEL_DEBUG) .build(); Rox.setup(this, options);
Rox.setup(ROLLOUT_KEY, { debugLevel: 'verbose' });
Rox.setup(ROLLOUT_KEY, { debugLevel: 'verbose' });
Rox.setup(ROLLOUT_KEY, { debugLevel: 'verbose' });
import {Rox} from 'rox-ssr'; Rox.setup(ROLLOUT_KEY, { debugLevel: 'verbose' });
JVM verbose logging is done using SLF4J library. In order to turn on verbosity of the SDK, you need to set the logger level for io.rollout to debug in your logging library configration. Here is anexample on how to turn on verbosity with Logback logger <?xml version="1.0" encoding="UTF-8"?> <configuration scan="false" debug="false"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> </encoder> </appender> <logger name="io.rollout" level="DEBUG"/> <root level="INFO"> <appender-ref ref="STDOUT" /> </root> </configuration>
public class internalLogger : ILogger { public void Debug(string message) { Console.WriteLine(message); } public void Debug(string message, Exception ex) { Console.WriteLine(message + ex.ToString()); } public void Warn(string message) { Console.WriteLine(message); } public void Warn(string message, Exception ex) { Console.WriteLine(message + ex.ToString()); } public void Error(string message) { Console.WriteLine(message); } public void Error(string message, Exception ex) { Console.WriteLine(message + ex.ToString()); } } var Options = new RoxOptions(new RoxOptions.RoxOptionsBuilder { Logger = new internalLogger() // commenting this line,"io.rollout" will be used } await Rox.Setup(<ROLLOUT_KEY>, Options);
from rox.server.rox_options import RoxOptions # example of a naive Logger class MyLogger: def error(self, msg, ex=None): print('error: %s exception: %s' %(msg, ex)) def warn(self, msg, ex=None): print('warn: %s' % msg) def debug(self, msg, ex=None): print('debug: %s' % msg) options = RoxOptions( logger=MyLogger() ) my_container = MyContainer() Rox.register('test', my_container) cancel_event = Rox.setup(<ROLLOUT_KEY>, options).result();
type logger struct { } func (*logger) Debug(message string, err interface{}) { fmt.Println("debug:", message) } func (*logger) Warn(message string, err interface{}) { fmt.Println("warn:", message) } func (*logger) Error(message string, err interface{}) { fmt.Println("error:", message) } options = RoxOptions( Logger: &logger{}, ) <-rox.Setup(<ROLLOUT_KEY>, options)
# example of a naive Logger, if not set ruby's logger will be used with STDOUT class Log def debug(message, ex = nil) puts 'debug msg:', message end def error(message, ex = nil) puts 'error msg:', message end def warn(message, ex = nil) puts 'warn msg:', message end end option = Rox::Server::RoxOptions.new( logger: Log.new ) container = Container.new Rox::Server::RoxServer.register('', container) Rox::Server::RoxServer.setup(<ROLLOUT_KEY>, option).join
$logFile = join(DIRECTORY_SEPARATOR, [ sys_get_temp_dir(), 'rollout', 'logs', 'demo.log' ]); LoggerFactory::setup((new MonologLoggerFactory()) ->setDefaultHandlers([ new StreamHandler($logFile, Logger::DEBUG) ]) );
void _file_logging_handler(void *target, RoxLogMessage *message) { assert(target); assert(message); FILE *file = (FILE *) target; fprintf(file, "(%s) %s\n", message->level_name, message->message); fflush(file); } int main(int argc, char **argv) { // creating a log config struct with debug log level RoxLoggingConfig cfg = ROX_LOGGING_CONFIG_INITIALIZER(RoxLogLevelDebug); // RoxLogLevel enum value // !!! custom handler code start !!! // example of writing logs to file instead of using default stdout FILE *file = fopen(LOG_FILE_PATH, "w"); if (!file) { fprintf(stderr, "Cannot open %s\n", LOG_FILE_PATH); return -1; } // setting target and handler - in case we want to change the default cfg.target = file; // default: stdout cfg.handler = &_file_logging_handler; // !!! custom handler code end !!! // initializing logging with the configurations created rox_logging_init(&cfg); // initialize rox RoxOptions *options = rox_options_create(); rox_setup(DEFAULT_API_KEY, options); // do rox things here // close rox_shutdown(); fclose(file); }
class LoggingHandler : public Rox::LogMessageHandlerInterface { public: void HandleLogMessage(Rox::LogMessage *message) { // do something with message } } int main(int argc, char **argv) { LoggingHandler loggingHandler; // to change to logging level Rox::Logging::SetLogLevel(RoxLogLevelDebug); // to change the default handler Rox::Logging::SetLogMessageHandler(&loginHandler); }