Skip to content

Commit

Permalink
logging: set up logging in capa.main
Browse files Browse the repository at this point in the history
this commit sets up logging in `capa.main` and uses a shared
`log_console` in `capa.helpers` for logging purposes
  • Loading branch information
fariss committed Sep 24, 2024
1 parent 1d7b743 commit 0e3cdad
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 38 deletions.
26 changes: 0 additions & 26 deletions capa/__init__.py
Original file line number Diff line number Diff line change
@@ -1,26 +0,0 @@
# Copyright (C) 2024 Mandiant, Inc. All Rights Reserved.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at: [package root]/LICENSE.txt
# Unless required by applicable law or agreed to in writing, software distributed under the License
# is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and limitations under the License.
import logging
from logging import Formatter

from rich.logging import RichHandler

# use [/] after the logger name to reset any styling,
# and prevent the color from carrying over to the message
LOGFORMAT = "[grey54]%(name)s[/]: %(message)s"

logging.basicConfig(level=logging.NOTSET)
logger = logging.getLogger()

if logger.hasHandlers():
logger.handlers.clear()

# markup=True, to allow the use of Rich's markup syntax in log messages
rich_handler = RichHandler(level=logging.NOTSET, markup=True, show_time=False)
rich_handler.setFormatter(Formatter(LOGFORMAT))
logger.addHandler(rich_handler)
4 changes: 3 additions & 1 deletion capa/capabilities/dynamic.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,9 @@ def find_dynamic_capabilities(
processes: List[ProcessHandle] = list(extractor.get_processes())
n_processes: int = len(processes)

with capa.helpers.CapaProgressBar(transient=True, disable=disable_progress) as pbar:
with capa.helpers.CapaProgressBar(
console=capa.helpers.log_console, transient=True, disable=disable_progress
) as pbar:
task = pbar.add_task("matching", total=n_processes, unit="processes")
for p in processes:
process_matches, thread_matches, call_matches, feature_count = find_process_capabilities(
Expand Down
4 changes: 3 additions & 1 deletion capa/capabilities/static.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,9 @@ def find_static_capabilities(
n_libs: int = 0
percentage: float = 0

with capa.helpers.CapaProgressBar(transient=True, disable=disable_progress) as pbar:
with capa.helpers.CapaProgressBar(
console=capa.helpers.log_console, transient=True, disable=disable_progress
) as pbar:
task = pbar.add_task(
"matching", total=n_funcs, unit="functions", postfix=f"skipped {n_libs} library functions, {percentage}%"
)
Expand Down
5 changes: 5 additions & 0 deletions capa/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from datetime import datetime

import msgspec.json
from rich.console import Console
from rich.progress import (
Task,
Text,
Expand Down Expand Up @@ -58,6 +59,10 @@
logger = logging.getLogger("capa")


# shared console used to redirect logging to stderr
log_console: Console = Console(stderr=True)


def hex(n: int) -> str:
"""render the given number using upper case hex, like: 0x123ABC"""
if n < 0:
Expand Down
40 changes: 31 additions & 9 deletions capa/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,24 @@
E_INVALID_INPUT_FORMAT = 25
E_INVALID_FEATURE_EXTRACTOR = 26

root_logger = logging.getLogger()
logging.basicConfig(level=logging.NOTSET)

# use [/] after the logger name to reset any styling,
# and prevent the color from carrying over to the message
LOGFORMAT = "[dim]%(name)s[/]: %(message)s"

if root_logger.hasHandlers():
root_logger.handlers.clear()

# markup=True, to allow the use of Rich's markup syntax in log messages
rich_handler = RichHandler(
level=logging.NOTSET, markup=True, show_time=False, show_path=True, console=capa.helpers.log_console
)
rich_handler.setFormatter(logging.Formatter(LOGFORMAT))
root_logger.addHandler(rich_handler)

logger = logging.getLogger("capa")
logger.propagate = False


class FilterConfig(TypedDict, total=False):
Expand Down Expand Up @@ -404,14 +420,6 @@ def handle_common_args(args):
raises:
ShouldExitError: if the program is invoked incorrectly and should exit.
"""
# use [/] after the logger name to reset any styling,
# and prevent the color from carrying over to the message
LOGFORMAT = "[dim]%(name)s[/]: %(message)s"

# markup=True, to allow the use of Rich's markup syntax in log messages
rich_handler = RichHandler(markup=True, show_time=False)
rich_handler.setFormatter(logging.Formatter(LOGFORMAT))
logger.addHandler(rich_handler)

if args.quiet:
logging.basicConfig(level=logging.WARNING)
Expand All @@ -426,6 +434,20 @@ def handle_common_args(args):
# disable vivisect-related logging, it's verbose and not relevant for capa users
set_vivisect_log_level(logging.CRITICAL)

# logger = logging.getLogger()

# # use [/] after the logger name to reset any styling,
# # and prevent the color from carrying over to the message
# LOGFORMAT = "[dim]%(name)s[/]: %(message)s"

# if logger.hasHandlers():
# logger.handlers.clear()

# # markup=True, to allow the use of Rich's markup syntax in log messages
# rich_handler = RichHandler(level=logging.NOTSET, markup=True, show_time=False, show_path=False, console=Console(stderr=True))
# rich_handler.setFormatter(logging.Formatter(LOGFORMAT))
# logger.addHandler(rich_handler)

if isinstance(sys.stdout, io.TextIOWrapper) or hasattr(sys.stdout, "reconfigure"):
# from sys.stdout type hint:
#
Expand Down
2 changes: 1 addition & 1 deletion scripts/profile-time.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ def main(argv=None):
except capa.main.ShouldExitError as e:
return e.status_code

with capa.helpers.CapaProgressBar() as progress:
with capa.helpers.CapaProgressBar(console=capa.helpers.log_console) as progress:
total_iterations = args.number * args.repeat
task = progress.add_task("profiling", total=total_iterations)

Expand Down

0 comments on commit 0e3cdad

Please sign in to comment.