Skip to content

Commit

Permalink
add new configurable logging
Browse files Browse the repository at this point in the history
  • Loading branch information
Gyorgy Orban committed Jan 16, 2018
1 parent d8a03a7 commit 1d5d47f
Show file tree
Hide file tree
Showing 62 changed files with 534 additions and 306 deletions.
33 changes: 9 additions & 24 deletions bin/CodeChecker.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,6 @@
from shared.ttypes import RequestFailed

from libcodechecker import libhandlers
from libcodechecker.logger import LoggerFactory


LOG = LoggerFactory.get_new_logger('MAIN')


def main(subcommands=None):
Expand Down Expand Up @@ -67,7 +63,7 @@ def signal_handler(sig, frame):
In this case, no database is used, and the results are printed on the standard
output.
CodeChecker check -b "cd ~/myproject && make\"""")
CodeChecker check -b "cd ~/myproject && make\" """)

subparsers = parser.add_subparsers(help='commands')

Expand All @@ -78,37 +74,33 @@ def signal_handler(sig, frame):
if len(sys.argv) > 1:
first_command = sys.argv[1]
if first_command in subcommands:
LOG.debug("Supplied an existing, valid subcommand: " +
first_command)

# Consider only the given command as an available one.
subcommands = [first_command]

for subcommand in subcommands:
LOG.debug("Creating arg parser for subcommand " + subcommand)

try:
libhandlers.add_subcommand(subparsers, str(subcommand))
except (IOError, ImportError):
LOG.warning("Couldn't import module for subcommand '" +
subcommand + "'... ignoring.")
print("Couldn't import module for subcommand '" +
subcommand + "'... ignoring.")
import traceback
traceback.print_exc(file=sys.stdout)

args = parser.parse_args()
if 'verbose' in args:
LoggerFactory.set_log_level(args.verbose)

args.func(args)

except KeyboardInterrupt as kb_err:
LOG.info(str(kb_err))
LOG.info("Interrupted by user...")
print(str(kb_err))
print("Interrupted by user...")
sys.exit(1)

except RequestFailed as thrift_ex:
LOG.info("Server error.")
LOG.info("Error code: " + str(thrift_ex.errorCode))
LOG.info("Error message: " + str(thrift_ex.message))
print("Server error.")
print("Error code: " + str(thrift_ex.errorCode))
print("Error message: " + str(thrift_ex.message))
sys.exit(1)

# Handle all exception, but print stacktrace. It is needed for atexit.
Expand All @@ -122,10 +114,6 @@ def signal_handler(sig, frame):

# -----------------------------------------------------------------------------
if __name__ == "__main__":
LOG.debug(sys.path)
LOG.debug(sys.version)
LOG.debug(sys.executable)
LOG.debug(os.environ.get('LD_LIBRARY_PATH'))

# Load the available CodeChecker subcommands.
# This list is generated dynamically by scripts/build_package.py, and is
Expand All @@ -135,7 +123,4 @@ def signal_handler(sig, frame):
with open(commands_cfg) as cfg_file:
commands = json.load(cfg_file)

LOG.debug("Available CodeChecker subcommands: ")
LOG.debug(commands)

main(commands)
56 changes: 56 additions & 0 deletions config/logger.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
{
"version": 1,
"disable_existing_loggers": true,
"formatters": {
"brief": {
"format": "[%(asctime)s] - %(message)s",
"datefmt": "%Y-%m-%d %H:%M"
},
"precise": {
"format": "[%(levelname)s][%(asctime)s] {%(name)s} [%(process)d] <%(thread)d> - %(filename)s:%(lineno)d %(funcName)s() - %(message)s",
"datefmt": "%Y-%m-%d %H:%M:%S"
}
},
"loggers": {
"analyzer": {
"level": "INFO",
"handlers": ["console"]
},
"analyzer.clangsa": {
"level": "INFO",
"handlers": ["console"]
},
"analyzer.tidy": {
"level": "INFO",
"handlers": ["console"]
},
"buildlogger": {
"level": "INFO",
"handlers": ["console"]
},
"profiler": {
"level": "INFO",
"handlers": ["console"]
},
"report": {
"level": "INFO",
"handlers": ["console"]
},
"server": {
"level": "INFO",
"handlers": ["console"]
},
"system": {
"level": "INFO",
"handlers": ["console"]
}
},
"handlers": {
"console": {
"class": "logging.StreamHandler",
"level": "INFO",
"formatter": "brief",
"stream": "ext://sys.stdout"
}
}
}
138 changes: 138 additions & 0 deletions docs/logging.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
# Log configuration

## Command line

Command line flag can be used to turn in CodeChecker debug mode. The different
subcommands can be given a `-v` flag which needs a parameter. Possible values
are `debug`, `debug_analyzer` and `info`. Default is `info`.

`debug_analyzer` switches analyzer related logs on:

~~~~~~~~~~~~~~~~~~~~~
CodeChecker check <name> -b <build_command> --verbose debug_analyzer
~~~~~~~~~~~~~~~~~~~~~

Turning on CodeChecker debug level logging is possible for the most
subcommands:

~~~~~~~~~~~~~~~~~~~~~
CodeChecker check <name> -b <build_command> --verbose debug
CodeChecker server -v <view_port> --verbose debug
~~~~~~~~~~~~~~~~~~~~~

## Change log configuration for the server

The log level for a server can be changed in two ways.

### 1. At the server start

Debug log can be enabled like this at the server start.
```
Codechecker server ... --verbose debug
```

The log levels can not be changed after the server was started.

### 2. While the server is running

The log configuration can be changed for a running server if it was started
in an environment where the `CC_LOG_CONFIG_PORT` environment variable is set.

```sh
CC_LOG_CONFIG_PORT='8888' Codechecker server ...
```
The running server will accept log configurations on the configured `8888` port.
This way the log configuration can be changed without a server restart.

#### Sending new configuration to a running server

Sending a new configuration to the server can be done easily with
`scripts/send_log_config.py` like this:
```
./send_log_config.py -c new_log_cfg.conf -p 8888
```

Sending a configuration can be done only on the same machine where the server was started. See further
details [here](https://docs.python.org/2/library/logging.config.html#logging.config.listen).

## Example debug log configuration with multiple handlers

For more information see: [logging-cookbook](https://docs.python.org/2/howto/logging-cookbook.html) or
[logging.config](https://docs.python.org/2/library/logging.config.html)

```json
{
"version": 1,
"disable_existing_loggers": true,
"formatters": {
"brief": {
"format": "[%(asctime)s] - %(message)s",
"datefmt": "%Y-%m-%d %H:%M"
},
"precise": {
"format": "[%(asctime)s] {%(name)s} [%(process)d] <%(thread)d> - %(filename)s:%(lineno)d %(funcName)s() - %(message)s",
"datefmt": "%Y-%m-%d %H:%M:%S"
}
},
"loggers": {
"analyzer": {
"level": "DEBUG",
"handlers": [ "console", "file" ]
},
"analyzer.tidy": {
"level": "DEBUG",
"handlers": [ "console", "file" ]
},
"analyzer.clangsa": {
"level": "DEBUG",
"handlers": [ "console", "file" ]
},
"server": {
"level": "DEBUG",
"handlers": [ "console", "file" , "daily_log"]
},
"buildlogger": {
"level": "DEBUG",
"handlers": [ "console", "file" ]
},
"report": {
"level": "DEBUG",
"handlers": [ "console", "file" ]
},
"system": {
"level": "DEBUG",
"handlers": [ "console", "file", "daily_log" ]
},
"profiler": {
"level": "DEBUG",
"handlers": [ "console", "file" ]
}
},
"handlers": {
"console": {
"class": "logging.StreamHandler",
"level": "DEBUG",
"formatter": "brief",
"stream": "ext://sys.stdout"
},
"file": {
"class": "logging.handlers.RotatingFileHandler",
"formatter": "precise",
"level": "DEBUG",
"filename": "file.log",
"encoding": "utf-8",
"maxBytes": 1000000,
"backupCount": 3
},
"daily_log": {
"class": "logging.handlers.TimedRotatingFileHandler",
"formatter": "precise",
"level": "DEBUG",
"filename": "daily.log",
"encoding": "utf-8",
"when": "D",
"interval": 1
}
}
}
```
21 changes: 1 addition & 20 deletions docs/user_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -1513,23 +1513,4 @@ http://www.postgresql.org/docs/current/static/libpq-pgpass.html

# <a name="debug"></a> Debugging CodeChecker

Command line flag can be used to turn in CodeChecker debug mode. The different
subcommands can be given a `-v` flag which needs a parameter. Possible values
are `debug`, `debug_analyzer` and `info`. Default is `info`.

`debug_analyzer` switches analyzer related logs on:

~~~~~~~~~~~~~~~~~~~~~
CodeChecker check <name> -b <build_command> --verbose debug_analyzer
~~~~~~~~~~~~~~~~~~~~~

Turning on CodeChecker debug level logging is possible for the most
subcommands:

~~~~~~~~~~~~~~~~~~~~~
CodeChecker check <name> -b <build_command> --verbose debug
CodeChecker server -v <view_port> --verbose debug
~~~~~~~~~~~~~~~~~~~~~

If debug logging is enabled and PostgreSQL database is used, PostgreSQL logs
are written to `postgresql.log` in the workspace directory.
To change the log levels check out the [logging](logging.md) documentation.
4 changes: 2 additions & 2 deletions libcodechecker/analyze/analysis_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@
from libcodechecker.analyze import analyzer_env
from libcodechecker.analyze import plist_parser
from libcodechecker.analyze.analyzers import analyzer_types
from libcodechecker.logger import LoggerFactory
from libcodechecker.logger import get_logger

LOG = LoggerFactory.get_new_logger('ANALYSIS MANAGER')
LOG = get_logger('analyzer')


def worker_result_handler(results, metadata, output_path):
Expand Down
4 changes: 2 additions & 2 deletions libcodechecker/analyze/analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@
import subprocess
import time

from libcodechecker.logger import LoggerFactory
from libcodechecker.logger import get_logger
from libcodechecker.analyze import analysis_manager
from libcodechecker.analyze import analyzer_env
from libcodechecker.analyze import ctu_manager
from libcodechecker.analyze import skiplist_handler
from libcodechecker.analyze.analyzers import analyzer_types

LOG = LoggerFactory.get_new_logger('ANALYZER')
LOG = get_logger('analyzer')


def prepare_actions(actions, enabled_analyzers):
Expand Down
4 changes: 2 additions & 2 deletions libcodechecker/analyze/analyzer_env.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@

import os

from libcodechecker.logger import LoggerFactory
from libcodechecker.logger import get_logger

LOG = LoggerFactory.get_new_logger('ENV')
LOG = get_logger('system')


def get_log_env(logfile, context, original_env):
Expand Down
4 changes: 2 additions & 2 deletions libcodechecker/analyze/analyzers/analyzer_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
import subprocess
import sys

from libcodechecker.logger import LoggerFactory
from libcodechecker.logger import get_logger

LOG = LoggerFactory.get_new_logger('ANALYZER (BASE)')
LOG = get_logger('analyzer')


class SourceAnalyzer(object):
Expand Down
4 changes: 2 additions & 2 deletions libcodechecker/analyze/analyzers/analyzer_clang_tidy.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@
import subprocess

from libcodechecker.analyze.analyzers import analyzer_base
from libcodechecker.logger import LoggerFactory
from libcodechecker.logger import get_logger
from libcodechecker.util import get_binary_in_path
from libcodechecker.analyze.analyzer_env import\
extend_analyzer_cmd_with_resource_dir

LOG = LoggerFactory.get_new_logger('CLANG TIDY')
LOG = get_logger('analyzer')


class ClangTidy(analyzer_base.SourceAnalyzer):
Expand Down
4 changes: 2 additions & 2 deletions libcodechecker/analyze/analyzers/analyzer_clangsa.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@
from libcodechecker.analyze.analyzers import analyzer_base
from libcodechecker.analyze.analyzers import ctu_triple_arch
from libcodechecker.analyze import analyzer_env
from libcodechecker.logger import LoggerFactory
from libcodechecker.logger import get_logger
from libcodechecker.util import get_binary_in_path
from libcodechecker.analyze.analyzer_env import\
extend_analyzer_cmd_with_resource_dir

LOG = LoggerFactory.get_new_logger('CLANGSA')
LOG = get_logger('analyzer')


class ClangSA(analyzer_base.SourceAnalyzer):
Expand Down
Loading

0 comments on commit 1d5d47f

Please sign in to comment.