Skip to content

Commit e694c10

Browse files
authored
Merge pull request #2 from adybbroe/add-logging
Add support for logging
2 parents d26b8d7 + 9a2f2f8 commit e694c10

File tree

2 files changed

+88
-9
lines changed

2 files changed

+88
-9
lines changed

pytroll_runner/__init__.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
2121
"""
2222
import argparse
23+
import logging
24+
import logging.config
2325
import os
2426
import re
2527
from contextlib import closing
@@ -31,25 +33,46 @@
3133
from posttroll.publisher import create_publisher_from_dict_config
3234
from posttroll.subscriber import create_subscriber_from_dict_config
3335

36+
logger = logging.getLogger('pytroll-runner')
37+
3438

3539
def main(args=None):
3640
"""Main script."""
3741
parsed_args = parse_args(args=args)
42+
setup_logging(parsed_args.log_config)
43+
44+
logger.info("Start generic pytroll-runner")
3845
return run_and_publish(parsed_args.config_file)
3946

4047

48+
def setup_logging(config_file):
49+
"""Setup the logging from a log config yaml file."""
50+
if config_file is not None:
51+
with open(config_file) as fd:
52+
log_dict = yaml.safe_load(fd.read())
53+
logging.config.dictConfig(log_dict)
54+
return
55+
56+
4157
def parse_args(args=None):
42-
"""Parse commandline arguments."""
58+
"""Parse command line arguments."""
4359
parser = argparse.ArgumentParser("Pytroll Runner",
4460
description="Automate third party software in a pytroll environment")
4561
parser.add_argument("config_file",
4662
help="The configuration file to run on.")
63+
parser.add_argument("-l", "--log_config",
64+
help="The log configuration yaml file.",
65+
default=None)
4766
return parser.parse_args(args)
4867

4968

5069
def run_and_publish(config_file):
5170
"""Run the command and publish the expected files."""
5271
command_to_call, subscriber_config, publisher_config = read_config(config_file)
72+
logger.debug("Subscriber config settings: ")
73+
for item in subscriber_config:
74+
logger.debug(f"{item} = {str(subscriber_config[item])}")
75+
5376
preexisting_files = check_existing_files(publisher_config)
5477

5578
with closing(create_publisher_from_dict_config(publisher_config["publisher_settings"])) as pub:
@@ -84,6 +107,7 @@ def read_config(config_file):
84107

85108
def run_from_new_subscriber(command, subscriber_settings):
86109
"""Run the command with files gotten from a new subscriber."""
110+
logger.debug("Run from new subscriber...")
87111
with closing(create_subscriber_from_dict_config(subscriber_settings)) as sub:
88112
return run_on_messages(command, sub.recv())
89113

@@ -106,6 +130,7 @@ def run_on_files(command, files):
106130
"""Run the command of files."""
107131
if not files:
108132
return
133+
logger.info(f"Start running command {command} on files {files}")
109134
process = Popen([os.fspath(command), *files], stdout=PIPE)
110135
out, _ = process.communicate()
111136
return out

pytroll_runner/tests/test_runner.py

Lines changed: 62 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"""Tests for the pytroll runner."""
22
import os
3+
import logging
34
from unittest import mock
45

56
import pytest
@@ -45,6 +46,29 @@
4546
"""
4647

4748

49+
log_config_content = """version: 1
50+
disable_existing_loggers: false
51+
handlers:
52+
console:
53+
class: logging.StreamHandler
54+
level: DEBUG
55+
stream: ext://sys.stdout
56+
root:
57+
level: DEBUG
58+
handlers: [console]
59+
"""
60+
61+
62+
@pytest.fixture()
63+
def log_config_file(tmp_path):
64+
"""Write a log config file."""
65+
log_config = tmp_path / "mylogconfig.yaml"
66+
with open(log_config, "w") as fobj:
67+
fobj.write(log_config_content)
68+
69+
return log_config
70+
71+
4872
@pytest.fixture()
4973
def command(tmp_path):
5074
"""Make a command script that just prints out the files it got."""
@@ -266,6 +290,7 @@ def single_file_to_glob(tmp_path):
266290
pattern = os.fspath(tmp_path / "file?")
267291
return pattern
268292

293+
269294
@pytest.fixture()
270295
def old_generated_file(tmp_path):
271296
"""Create a single file to glob."""
@@ -276,7 +301,7 @@ def old_generated_file(tmp_path):
276301
return filename
277302

278303

279-
def test_run_and_publish(tmp_path, command_bla, files_to_glob):
304+
def test_run_and_publish(caplog, tmp_path, command_bla, files_to_glob):
280305
"""Test run and publish."""
281306
sub_config = dict(nameserver=False, addresses=["ipc://bla"])
282307
pub_config = dict(publisher_settings=dict(nameservers=False, port=1979),
@@ -294,12 +319,17 @@ def test_run_and_publish(tmp_path, command_bla, files_to_glob):
294319
data = {"dataset": [{"uri": os.fspath(tmp_path / f), "uid": f} for f in some_files]}
295320
messages = [Message("some_topic", "dataset", data=data)]
296321

297-
with patched_subscriber_recv(messages):
298-
with patched_publisher() as published_messages:
299-
run_and_publish(yaml_file)
300-
assert len(published_messages) == 1
301-
for ds, filename in zip(published_messages[0].data["dataset"], some_files):
302-
assert ds["uid"] == filename + ".bla"
322+
with caplog.at_level(logging.DEBUG):
323+
with patched_subscriber_recv(messages):
324+
with patched_publisher() as published_messages:
325+
run_and_publish(yaml_file)
326+
assert len(published_messages) == 1
327+
for ds, filename in zip(published_messages[0].data["dataset"], some_files):
328+
assert ds["uid"] == filename + ".bla"
329+
330+
assert "Subscriber config settings: " in caplog.text
331+
assert "addresses = ['ipc://bla']" in caplog.text
332+
assert "nameserver = False" in caplog.text
303333

304334

305335
def test_run_and_publish_does_not_pick_old_files(tmp_path, command_bla, files_to_glob, old_generated_file):
@@ -370,7 +400,6 @@ def test_run_and_publish_with_files_from_log(tmp_path, command_aws):
370400
assert published_messages[0].data["uri"] == "/local_disk/aws_test/test/RAD_AWS_1B/" + expected
371401

372402

373-
374403
def test_config_reader(command, tmp_path):
375404
"""Test the config reader."""
376405
sub_config = dict(nameserver=False, addresses=["ipc://bla"])
@@ -383,6 +412,7 @@ def test_config_reader(command, tmp_path):
383412
with open(yaml_file, "w") as fd:
384413
fd.write(yaml.dump(test_config))
385414
command_to_call, subscriber_config, publisher_config = read_config(yaml_file)
415+
386416
assert subscriber_config == sub_config
387417
assert command_to_call == command_path
388418
assert publisher_config == pub_config
@@ -398,3 +428,27 @@ def test_main_crashes_when_config_file_missing():
398428
"""Test that main crashes when the config file is missing."""
399429
with pytest.raises(FileNotFoundError):
400430
main(["moose_config.yaml"])
431+
432+
433+
def test_main_parse_log_configfile(tmp_path, command, log_config_file):
434+
"""Test that when parsing a log-config yaml file logging is being setup"""
435+
sub_config = dict(nameserver=False, addresses=["ipc://bla"])
436+
pub_settings = dict(nameserver=False, name='blabla')
437+
pub_config = dict(topic="/hi/there/",
438+
expected_files='*.bufr',
439+
publisher_settings=pub_settings)
440+
command_path = os.fspath(command)
441+
test_config = dict(subscriber_config=sub_config,
442+
script=command_path,
443+
publisher_config=pub_config)
444+
445+
yaml_file = tmp_path / "config.yaml"
446+
with open(yaml_file, "w") as fd:
447+
fd.write(yaml.dump(test_config))
448+
449+
messages = []
450+
with patched_subscriber_recv(messages):
451+
with patched_publisher() as published_messages:
452+
main([str(yaml_file), '-l', str(log_config_file)])
453+
454+
assert isinstance(logging.getLogger('').handlers[0], logging.StreamHandler)

0 commit comments

Comments
 (0)