netdata_tsrelay.nim
changeset 9 aa9d537f7067
parent 8 1ef3f2d6d10e
child 11 475c9942eb15
equal deleted inserted replaced
8:1ef3f2d6d10e 9:aa9d537f7067
     1 # vim: set et nosta sw=4 ts=4 :
     1 # vim: set et nosta sw=4 ts=4 :
     2 # im: set et nosta sw=4 ts=4 ft=nim : 
       
     3 #
     2 #
     4 # Copyright (c) 2018, Mahlon E. Smith <mahlon@martini.nu>
     3 # Copyright (c) 2018, Mahlon E. Smith <mahlon@martini.nu>
     5 # All rights reserved.
     4 # All rights reserved.
     6 # Redistribution and use in source and binary forms, with or without
     5 # Redistribution and use in source and binary forms, with or without
     7 # modification, are permitted provided that the following conditions are met:
     6 # modification, are permitted provided that the following conditions are met:
    73         verbose:     bool    # Be informative
    72         verbose:     bool    # Be informative
    74         debug:       bool    # Spew out raw data
    73         debug:       bool    # Spew out raw data
    75 
    74 
    76 # Global configuration
    75 # Global configuration
    77 var conf: Config
    76 var conf: Config
       
    77 
    78 
    78 
    79 proc hl( msg: string, fg: ForegroundColor, bright=false ): string =
    79 proc hl( msg: string, fg: ForegroundColor, bright=false ): string =
    80     ## Quick wrapper for color formatting a string, since the 'terminal'
    80     ## Quick wrapper for color formatting a string, since the 'terminal'
    81     ## module only deals with stdout directly.
    81     ## module only deals with stdout directly.
    82     if not isatty(stdout): return msg
    82     if not isatty(stdout): return msg
   169 
   169 
   170     db.close
   170     db.close
   171 
   171 
   172 
   172 
   173 proc process( client: Socket, address: string ): void =
   173 proc process( client: Socket, address: string ): void =
   174     ## Do the work for a connected client within a thread.
   174     ## Do the work for a connected client within child process.
   175     ## Returns the formatted json data keyed on sample time.
       
   176     let t0 = cpu_time()
   175     let t0 = cpu_time()
   177     var raw_data = client.fetch_data
   176     var raw_data = client.fetch_data
   178 
   177 
   179     # Done with the socket, netdata will automatically
   178     # Done with the socket, netdata will automatically
   180     # reconnect.  Save local resources/file descriptors
   179     # reconnect.  Save local resources/file descriptors
   203 
   202 
   204 proc serverloop( conf: Config ): void =
   203 proc serverloop( conf: Config ): void =
   205     ## Open a database connection, bind to the listening socket,
   204     ## Open a database connection, bind to the listening socket,
   206     ## and start serving incoming netdata streams.
   205     ## and start serving incoming netdata streams.
   207     let db = open( "", "", "", conf.dbopts )
   206     let db = open( "", "", "", conf.dbopts )
       
   207     db.close
   208     if conf.verbose: echo( "Successfully tested connection to the backend database.".hl( fgGreen ) )
   208     if conf.verbose: echo( "Successfully tested connection to the backend database.".hl( fgGreen ) )
   209     db.close
   209 
       
   210     # Ensure children are properly reaped.
       
   211     #
       
   212     var sa: Sigaction
       
   213     sa.sa_handler = SIG_IGN
       
   214     discard sigaction( SIGCHLD, sa )
   210 
   215 
   211     # Setup listening socket.
   216     # Setup listening socket.
   212     #
   217     #
   213     var server = newSocket()
   218     var server = newSocket()
   214     server.set_sock_opt( OptReuseAddr, true )
   219     server.set_sock_opt( OptReuseAddr, true )
   228     #
   233     #
   229     while true:
   234     while true:
   230         var
   235         var
   231             client  = new Socket
   236             client  = new Socket
   232             address = ""
   237             address = ""
   233             status: cint = 0
   238 
   234 
   239         # Block, waiting for new connections.
   235         server.acceptAddr( client, address ) # block
   240         server.acceptAddr( client, address )
   236 
   241 
   237         if fork() == 0:
   242         if fork() == 0:
   238             server.close
   243             server.close
   239             client.process( address )
   244             client.process( address )
   240             quit( 0 )
   245             quit( 0 )
   241 
   246 
   242         client.close
   247         client.close
   243 
       
   244         discard waitpid( P_ALL, status, WNOHANG ) # reap all previous children
       
   245         when defined( testing ): dumpNumberOfInstances()
   248         when defined( testing ): dumpNumberOfInstances()
   246 
   249 
   247 
   250 
   248 proc parse_cmdline: Config =
   251 proc parse_cmdline: Config =
   249     ## Populate the config object with the user's preferences.
   252     ## Populate the config object with the user's preferences.
   292         of cmdEnd: assert( false ) # shouldn't reach here ever
   295         of cmdEnd: assert( false ) # shouldn't reach here ever
   293 
   296 
   294 
   297 
   295 when isMainModule:
   298 when isMainModule:
   296     system.addQuitProc( resetAttributes )
   299     system.addQuitProc( resetAttributes )
   297 
       
   298     conf = parse_cmdline()
   300     conf = parse_cmdline()
   299     if conf.debug: echo hl( $conf, fgYellow )
   301     if conf.debug: echo hl( $conf, fgYellow )
   300 
       
   301     serverloop( conf )
   302     serverloop( conf )
   302 
   303