def setup_logger(config):
    logger = logging.getLogger(PROGRAM_NAME)
    num_level = getattr(
        logging,
        config.get('daemon', 'loglevel').upper(),
        None
    )
    logger.setLevel(num_level)
    lengths = []
    for section in config:
        lengths.append(len(section))
    width = sorted(lengths)[-1] + 1
    def log_format():
        supported_keys = [
            'asctime',
            'levelname',
            'process',
            'threadName',
            'message',
        ]
        return ' '.join(['%({0:s})'.format(i) for i in supported_keys])
    custom_format = log_format()
    json_formatter = CustomJsonFormatter(custom_format,
                                         prefix=PROGRAM_NAME + ': ')
    formatter = logging.Formatter(
        '%(asctime)s {program}[%(process)d] %(levelname)-8s '
        '%(threadName)-{width}s %(message)s'
        .format(program=PROGRAM_NAME, width=width)
    )
    if config.has_option('daemon', 'log_file'):
        file_handler = logging.handlers.RotatingFileHandler(
            config.get('daemon', 'log_file'),
            maxBytes=config.getint('daemon', 'log_maxbytes'),
            backupCount=config.getint('daemon', 'log_backups')
        )
        if config.getboolean('daemon', 'json_log_file'):
            file_handler.setFormatter(json_formatter)
        else:
            file_handler.setFormatter(formatter)
        logger.addHandler(file_handler)
    if config.has_option('daemon', 'log_server'):
        udp_handler = logging.handlers.SysLogHandler(
            (
                config.get('daemon', 'log_server'),
                config.getint('daemon', 'log_server_port')
            )
        )
        if config.getboolean('daemon', 'json_log_server'):
            udp_handler.setFormatter(json_formatter)
        else:
            udp_handler.setFormatter(formatter)
        logger.addHandler(udp_handler)
    if (not config.has_option('daemon', 'log_file')
            and not config.has_option('daemon', 'log_server')):
        stream_handler = logging.StreamHandler()
        if config.getboolean('daemon', 'json_stdout'):
            stream_handler.setFormatter(json_formatter)
        else:
            stream_handler.setFormatter(formatter)
        logger.addHandler(stream_handler)
    if config.has_option('daemon', 'stderr_file'):
        sys.stderr = CustomRotatingFileLogger(
            filepath=config.get('daemon', 'stderr_file'),
            maxbytes=config.getint('daemon', 'log_maxbytes'),
            backupcount=config.getint('daemon', 'log_backups')
        )
    elif (config.has_option('daemon', 'stderr_log_server')
          and not config.has_option('daemon', 'stderr_file')):
        sys.stderr = CustomUdpLogger(
            server=config.get('daemon', 'log_server'),
            port=config.getint('daemon', 'log_server_port')
        )
    else:
        print('messages for unhandled exceptions will go to STDERR')
    return logger