omdnotificationforwarder 4.2__tar.gz → 4.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/PKG-INFO +3 -3
  2. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/README.md +1 -0
  3. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/bin/notificationforwarder +2 -2
  4. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/pyproject.toml +3 -4
  5. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/src/notificationforwarder/baseclass.py +1 -1
  6. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/src/notificationforwarder/nostr/formatter.py +3 -15
  7. omdnotificationforwarder-4.3/src/notificationforwarder/nostr/forwarder.py +130 -0
  8. omdnotificationforwarder-4.3/src/notificationforwarder/util.py +37 -0
  9. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/tests/test_alertmanager.py +3 -2
  10. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/tests/test_formatter.py +58 -1
  11. omdnotificationforwarder-4.3/tests/test_nostr.py +355 -0
  12. omdnotificationforwarder-4.2/src/notificationforwarder/nostr/forwarder.py +0 -141
  13. omdnotificationforwarder-4.2/tests/test_nostr.py +0 -261
  14. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/.gitignore +0 -0
  15. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/src/notificationforwarder/component_loader.py +0 -0
  16. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/src/notificationforwarder/email/formatter.py +0 -0
  17. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/src/notificationforwarder/email/forwarder.py +0 -0
  18. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/src/notificationforwarder/example/formatter.py +0 -0
  19. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/src/notificationforwarder/example/forwarder.py +0 -0
  20. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/src/notificationforwarder/json/__init__.py +0 -0
  21. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/src/notificationforwarder/json/logger.py +0 -0
  22. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/src/notificationforwarder/naemonlog/reporter.py +0 -0
  23. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/src/notificationforwarder/nostr/__init__.py +0 -0
  24. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/src/notificationforwarder/oauth2webhook/__init__.py +0 -0
  25. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/src/notificationforwarder/oauth2webhook/forwarder.py +0 -0
  26. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/src/notificationforwarder/rabbitmq/formatter.py +0 -0
  27. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/src/notificationforwarder/rabbitmq/forwarder.py +0 -0
  28. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/src/notificationforwarder/runtime_config.py +0 -0
  29. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/src/notificationforwarder/runtime_flow.py +0 -0
  30. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/src/notificationforwarder/spool.py +0 -0
  31. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/src/notificationforwarder/syslog/formatter.py +0 -0
  32. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/src/notificationforwarder/syslog/forwarder.py +0 -0
  33. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/src/notificationforwarder/telegram/forwarder.py +0 -0
  34. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/src/notificationforwarder/text/__init__.py +0 -0
  35. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/src/notificationforwarder/text/logger.py +0 -0
  36. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/src/notificationforwarder/webhook/forwarder.py +0 -0
  37. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/tests/pythonpath/lib/python/notificationforwarder/split1/forwarder.py +0 -0
  38. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/tests/pythonpath/lib/python/notificationforwarder/split2/formatter.py +0 -0
  39. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/tests/pythonpath/lib/python/notificationforwarder/split2/forwarder.py +0 -0
  40. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/tests/pythonpath/lib/python/notificationforwarder/split3/formatter.py +0 -0
  41. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/tests/pythonpath/lib/python/notificationforwarder/split3/forwarder.py +0 -0
  42. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/tests/pythonpath/local/lib/python/notificationforwarder/alertmanager_servicenow/formatter.py +0 -0
  43. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/tests/pythonpath/local/lib/python/notificationforwarder/bayern/formatter.py +0 -0
  44. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/tests/pythonpath/local/lib/python/notificationforwarder/datadup/formatter.py +0 -0
  45. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/tests/pythonpath/local/lib/python/notificationforwarder/datapost/formatter.py +0 -0
  46. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/tests/pythonpath/local/lib/python/notificationforwarder/discard/formatter.py +0 -0
  47. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/tests/pythonpath/local/lib/python/notificationforwarder/split1/formatter.py +0 -0
  48. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/tests/pythonpath/local/lib/python/notificationforwarder/split2/forwarder.py +0 -0
  49. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/tests/pythonpath/local/lib/python/notificationforwarder/split3/formatter.py +0 -0
  50. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/tests/pythonpath/local/lib/python/notificationforwarder/split3/forwarder.py +0 -0
  51. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/tests/pythonpath/local/lib/python/notificationforwarder/split4/formatter.py +0 -0
  52. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/tests/pythonpath/local/lib/python/notificationforwarder/split4/forwarder.py +0 -0
  53. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/tests/pythonpath/local/lib/python/notificationforwarder/ticketsystem/forwarder.py +0 -0
  54. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/tests/pythonpath/local/lib/python/notificationforwarder/ticketsystem/reporter.py +0 -0
  55. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/tests/pythonpath/local/lib/python/notificationforwarder/vong/formatter.py +0 -0
  56. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/tests/test_builtin_plugins_focus.py +0 -0
  57. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/tests/test_classes.py +0 -0
  58. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/tests/test_delivery_resilience.py +0 -0
  59. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/tests/test_discard.py +0 -0
  60. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/tests/test_logger.py +0 -0
  61. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/tests/test_oauth2webhook.py +0 -0
  62. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/tests/test_package.py +0 -0
  63. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/tests/test_paths.py +0 -0
  64. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/tests/test_reporter.py +0 -0
  65. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/tests/test_runtime_foundation.py +0 -0
  66. {omdnotificationforwarder-4.2 → omdnotificationforwarder-4.3}/tests/test_webhook.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: omdnotificationforwarder
3
- Version: 4.2
3
+ Version: 4.3
4
4
  Summary: A framework for notification scripts for OMD
5
5
  Project-URL: Homepage, https://github.com/lausser/noteventificationforhandlerwarder
6
6
  Project-URL: Bug Tracker, https://github.com/lausser/noteventificationforhandlerwarder/issues
@@ -9,10 +9,9 @@ Classifier: License :: OSI Approved :: MIT License
9
9
  Classifier: Operating System :: OS Independent
10
10
  Classifier: Programming Language :: Python :: 3
11
11
  Requires-Python: >=3.6.1
12
- Requires-Dist: coshsh
13
12
  Requires-Dist: jinja2
14
13
  Provides-Extra: nostr
15
- Requires-Dist: pynostr; extra == 'nostr'
14
+ Requires-Dist: nostr-sdk; extra == 'nostr'
16
15
  Provides-Extra: test
17
16
  Requires-Dist: flake8; extra == 'test'
18
17
  Requires-Dist: pytest; extra == 'test'
@@ -25,6 +24,7 @@ Description-Content-Type: text/markdown
25
24
  In this framework, two aspects are in the focus. How to transport a notification to the recipient system and in which format.
26
25
  In the beginning, Naemon or one of the other monitoring cores will execute a command line. The actual script and the individual command line parameters are defined in a command definition. Typical parameters are (i use the notation of Nagios macros) HOSTNAME, SERVICEDESC, SERVICESTATE, SERVICEOUTPUT. These snippets need to be put together to some kind of payload suitable for the receiving system. And then this payload must be transported to it. We call the two components *formatter* and *forwarder*. The formatter takes the raw input data and creates a payload and the forwarder transmits the payload to the destination.
27
26
  What the framework does for you behind the scenes: When forwarding to a recipient fails, the event is saved in a local sqlite database for a certain time and re-sent when the script is called next time and the recipient is available again. Logging of successful and of course failed deliveries is also done automatically.
27
+ Logging uses the framework's native setup with the standard logfile naming and format used by the built-in tools.
28
28
  There is also a component *reporter* which will rarely be used. It's purpose is to run additional code after a successful or failed delivery.
29
29
 
30
30
  Let me list some of the formatter/forwarder combinations which are usually found in enterprise environments:
@@ -3,6 +3,7 @@
3
3
  In this framework, two aspects are in the focus. How to transport a notification to the recipient system and in which format.
4
4
  In the beginning, Naemon or one of the other monitoring cores will execute a command line. The actual script and the individual command line parameters are defined in a command definition. Typical parameters are (i use the notation of Nagios macros) HOSTNAME, SERVICEDESC, SERVICESTATE, SERVICEOUTPUT. These snippets need to be put together to some kind of payload suitable for the receiving system. And then this payload must be transported to it. We call the two components *formatter* and *forwarder*. The formatter takes the raw input data and creates a payload and the forwarder transmits the payload to the destination.
5
5
  What the framework does for you behind the scenes: When forwarding to a recipient fails, the event is saved in a local sqlite database for a certain time and re-sent when the script is called next time and the recipient is available again. Logging of successful and of course failed deliveries is also done automatically.
6
+ Logging uses the framework's native setup with the standard logfile naming and format used by the built-in tools.
6
7
  There is also a component *reporter* which will rarely be used. It's purpose is to run additional code after a successful or failed delivery.
7
8
 
8
9
  Let me list some of the formatter/forwarder combinations which are usually found in enterprise environments:
@@ -6,7 +6,7 @@ import logging.handlers
6
6
  import os
7
7
  import sys
8
8
  #import logging
9
- from coshsh.util import setup_logging
9
+ from notificationforwarder.util import setup_logging
10
10
  from notificationforwarder import baseclass
11
11
  import traceback
12
12
 
@@ -78,7 +78,7 @@ Example for an HTTP-based reporter:
78
78
  help='Logger type: text (default) or json, or custom logger module',
79
79
  default='text')
80
80
  parser.add_argument('--version', action='version',
81
- version=f'%(prog)s 4.2')
81
+ version=f'%(prog)s 4.3')
82
82
 
83
83
  args = parser.parse_args()
84
84
  if not hasattr(args, 'formatter'):
@@ -1,5 +1,5 @@
1
1
  [build-system]
2
- requires = ["hatchling", "coshsh"]
2
+ requires = ["hatchling"]
3
3
  build-backend = "hatchling.build"
4
4
 
5
5
  [tool.hatch.build]
@@ -21,7 +21,7 @@ packages = ["src/notificationforwarder"]
21
21
 
22
22
  [project]
23
23
  name = "omdnotificationforwarder"
24
- version = "4.2"
24
+ version = "4.3"
25
25
  authors = [
26
26
  { name="Gerhard Lausser", email="lausser@yahoo.com" },
27
27
  ]
@@ -34,13 +34,12 @@ classifiers = [
34
34
  "Operating System :: OS Independent",
35
35
  ]
36
36
  dependencies = [
37
- "coshsh",
38
37
  "jinja2",
39
38
  ]
40
39
 
41
40
  [project.optional-dependencies]
42
41
  nostr = [
43
- "pynostr",
42
+ "nostr-sdk",
44
43
  ]
45
44
  test = [
46
45
  "requests",
@@ -11,7 +11,7 @@ except ImportError:
11
11
  import json
12
12
 
13
13
  import logging
14
- from coshsh.util import setup_logging
14
+ from notificationforwarder.util import setup_logging
15
15
  from importlib import import_module
16
16
 
17
17
  from notificationforwarder.component_loader import (
@@ -1,14 +1,3 @@
1
- """Generate a Nostr keypair and derive bech32 values.
2
-
3
- ```python
4
- from pynostr.key import PrivateKey
5
-
6
- private_key = PrivateKey()
7
- print(private_key.bech32()) # nsec1...
8
- print(private_key.public_key.bech32()) # npub1...
9
- ```
10
- """
11
-
12
1
  import json
13
2
 
14
3
  from notificationforwarder.baseclass import NotificationFormatter
@@ -25,11 +14,11 @@ class NostrFormatter(NotificationFormatter):
25
14
  def _build_tags(self, host, service, state, extra_tags=None):
26
15
  tags = [["t", "monitoring"]]
27
16
  if host:
28
- tags.append(["host", host])
17
+ tags.append(["t", "host=" + host])
29
18
  if service:
30
- tags.append(["service", service])
19
+ tags.append(["t", "service=" + service])
31
20
  if state:
32
- tags.append(["state", state])
21
+ tags.append(["t", "state=" + state])
33
22
  if isinstance(extra_tags, str):
34
23
  try:
35
24
  extra_tags = json.loads(extra_tags)
@@ -54,7 +43,6 @@ class NostrFormatter(NotificationFormatter):
54
43
  ]
55
44
  content = "\n".join(lines)
56
45
  event.payload = {
57
- "kind": 4,
58
46
  "content": content,
59
47
  "tags": self._build_tags(
60
48
  host,
@@ -0,0 +1,130 @@
1
+ import asyncio
2
+
3
+ try:
4
+ from nostr_sdk import Client, Keys, NostrSigner, PublicKey, RelayUrl, Tag, uniffi_set_event_loop
5
+ except ImportError as exc:
6
+ raise ImportError("missing nostr-sdk") from exc
7
+
8
+ from notificationforwarder.baseclass import NotificationForwarder, timeout
9
+
10
+
11
+ class NostrForwarder(NotificationForwarder):
12
+ def __init__(self, opts):
13
+ super(self.__class__, self).__init__(opts)
14
+ setattr(self, "relays", getattr(self, "relays", "wss://relay.damus.io"))
15
+ setattr(self, "relay_urls", getattr(self, "relay_urls", self.relays))
16
+ setattr(self, "nsec", getattr(self, "nsec", None))
17
+ setattr(self, "timeout_seconds", int(getattr(self, "timeout_seconds", 6)))
18
+
19
+ def _relay_list(self):
20
+ relays = self.relay_urls if self.relay_urls is not None else self.relays
21
+ if isinstance(relays, str):
22
+ return [relay.strip() for relay in relays.split(",") if relay.strip()]
23
+ if isinstance(relays, (list, tuple)):
24
+ return [str(relay).strip() for relay in relays if str(relay).strip()]
25
+ return []
26
+
27
+ def _keys(self):
28
+ if not self.nsec:
29
+ raise ValueError("nsec is required for Nostr publishing")
30
+ return Keys.parse(self.nsec)
31
+
32
+ def _public_key(self, value):
33
+ if isinstance(value, PublicKey):
34
+ return value
35
+ if not isinstance(value, str):
36
+ raise ValueError("receiver public key must be a string or PublicKey")
37
+ return PublicKey.parse(value)
38
+
39
+ def _tags(self, formatted_event):
40
+ tags = []
41
+ payload = formatted_event.payload or {}
42
+ tag_values = payload.get("tags", [])
43
+ if isinstance(tag_values, str):
44
+ import json
45
+
46
+ try:
47
+ tag_values = json.loads(tag_values)
48
+ except Exception:
49
+ tag_values = []
50
+ if isinstance(tag_values, (list, tuple)):
51
+ for tag in tag_values:
52
+ if isinstance(tag, (list, tuple)) and tag:
53
+ tags.append(Tag.parse(list(tag)))
54
+ return tags
55
+
56
+ def _configured_tags(self):
57
+ tag_values = getattr(self, "tags", [])
58
+ if isinstance(tag_values, str):
59
+ import json
60
+
61
+ try:
62
+ tag_values = json.loads(tag_values)
63
+ except Exception:
64
+ tag_values = []
65
+ return tag_values if isinstance(tag_values, (list, tuple)) else []
66
+
67
+ def _nip_mode(self):
68
+ return getattr(self, "nip_mode", "nip04")
69
+
70
+ async def _send_private_msg(self, relay_urls, receiver_pubkey, message, tags):
71
+ uniffi_set_event_loop(asyncio.get_running_loop())
72
+ keys = self._keys()
73
+ signer = NostrSigner.keys(keys)
74
+ client = Client(signer)
75
+ relay_urls = [RelayUrl.parse(url) for url in relay_urls]
76
+
77
+ for relay_url in relay_urls:
78
+ await client.add_relay(relay_url)
79
+
80
+ await client.connect()
81
+ return await client.send_private_msg_to(relay_urls, receiver_pubkey, message, tags)
82
+
83
+ async def _send_nip04_dm(self, relay_urls, receiver_pubkey, message):
84
+ uniffi_set_event_loop(asyncio.get_running_loop())
85
+ keys = self._keys()
86
+ signer = NostrSigner.keys(keys)
87
+ client = Client(signer)
88
+ relay_urls = [RelayUrl.parse(url) for url in relay_urls]
89
+
90
+ for relay_url in relay_urls:
91
+ await client.add_relay(relay_url)
92
+
93
+ await client.connect()
94
+ return await client.send_private_msg_to(relay_urls, receiver_pubkey, message, [])
95
+
96
+ @timeout(30)
97
+ def submit(self, event):
98
+ relay_urls = self._relay_list()
99
+ if not relay_urls:
100
+ logger.critical("Nostr publish failed: no relays configured")
101
+ return False
102
+
103
+ payload = event.payload or {}
104
+ nip_mode = self._nip_mode()
105
+ tags = self._configured_tags() or payload.get("tags", [])
106
+ recipient_pubkey = None
107
+ for tag in tags or []:
108
+ if isinstance(tag, (list, tuple)) and len(tag) > 1 and tag[0] == "p":
109
+ recipient_pubkey = self._public_key(tag[1])
110
+ break
111
+ if recipient_pubkey is None:
112
+ raise ValueError("Nostr DM requires a recipient p tag")
113
+
114
+ try:
115
+ message = payload.get("content", event.summary or str(payload))
116
+ nip_mode = self._nip_mode()
117
+ logger.debug("Nostr NIP mode: {}".format(nip_mode))
118
+ if nip_mode == "nip17":
119
+ # For NIP-17, use tags from payload (like [["t", "monitoring"]])
120
+ tags = self._tags(event)
121
+ asyncio.run(self._send_private_msg(relay_urls, recipient_pubkey, message, tags))
122
+ else:
123
+ # NIP-04: send without tags (nostr-sdk doesn't support NIP-04 tags easily)
124
+ asyncio.run(self._send_nip04_dm(relay_urls, recipient_pubkey, message))
125
+ logger.info("published Nostr DM: {}".format(event.summary))
126
+ self.no_more_logging()
127
+ return True
128
+ except Exception as exc:
129
+ logger.critical("Nostr publish failed: {}".format(str(exc)))
130
+ return False
@@ -0,0 +1,37 @@
1
+ import logging
2
+ from logging.handlers import RotatingFileHandler
3
+ from pathlib import Path
4
+ import sys
5
+
6
+
7
+ def setup_logging(logdir=".", logfile="notificationforwarder.log", scrnloglevel=logging.INFO, txtloglevel=logging.INFO, format="%(asctime)s %(process)d - %(levelname)s - %(message)s", backup_count=3):
8
+ logdir_path = Path(logdir)
9
+ logdir_path.mkdir(parents=True, exist_ok=True)
10
+
11
+ logfile_path = Path(logfile)
12
+ abs_logfile = logfile_path if logfile_path.is_absolute() else logdir_path / logfile_path
13
+ abs_logfile.touch(exist_ok=True)
14
+ logger_name = abs_logfile.name[:-4] if abs_logfile.name.endswith(".log") else abs_logfile.name
15
+ logger = logging.getLogger(logger_name)
16
+ logger.setLevel(logging.DEBUG)
17
+ logger.propagate = False
18
+
19
+ for handler in list(logger.handlers):
20
+ handler.close()
21
+ logger.removeHandler(handler)
22
+
23
+ formatter = logging.Formatter(format)
24
+
25
+ file_handler = RotatingFileHandler(str(abs_logfile), maxBytes=20 * 1024 * 1024, backupCount=backup_count, delay=True)
26
+ file_handler.setFormatter(formatter)
27
+ file_handler.setLevel(txtloglevel)
28
+ logger.addHandler(file_handler)
29
+
30
+ console_handler = logging.StreamHandler(sys.stderr)
31
+ console_handler.setFormatter(formatter)
32
+ console_handler.setLevel(scrnloglevel)
33
+ logger.addHandler(console_handler)
34
+
35
+ logger.debug("Logger initialized.")
36
+
37
+ return logger
@@ -149,7 +149,7 @@ def test_alertmanager_forwarder(setup):
149
149
  }
150
150
 
151
151
 
152
- amgw = notificationforwarder.baseclass.new("webhook", None, "alertmanager_servicenow", False, False, forwarderopts)
152
+ amgw = notificationforwarder.baseclass.new("webhook", None, "alertmanager_servicenow", True, True, forwarderopts)
153
153
  famgw = amgw.new_formatter()
154
154
  assert famgw.__class__.__name__ == "AlertmanagerServicenowFormatter"
155
155
  assert famgw.__module_file__.endswith("pythonpath/local/lib/python/notificationforwarder/alertmanager_servicenow/formatter.py")
@@ -158,9 +158,10 @@ def test_alertmanager_forwarder(setup):
158
158
 
159
159
  amgw.forward(eventopts)
160
160
  log = open(get_logfile(amgw)).read()
161
+ assert "event has no node" in log
162
+ assert "replace node with 4490.example.net" in log
161
163
  assert re.search(r'success: alertmanager sends 2 alarms.*result is .*"records": 2.*4490.*4491.*', log, flags=re.MULTILINE)
162
164
 
163
165
  http_server.shutdown()
164
166
 
165
167
 
166
-
@@ -91,6 +91,64 @@ def test_split3_forwarder_split4_formatter(setup):
91
91
  assert re.search(r'forwarder '+split3.__module_file__, log)
92
92
  assert re.search(r'formatter '+fsplit3.__module_file__, log)
93
93
 
94
+
95
+ def test_formatter_module_logging_uses_runtime_logfile(setup):
96
+ forwarderopts = {
97
+ "username": "i_bims",
98
+ "password": "dem_is_geheim"
99
+ }
100
+ eventopts = {
101
+ "alertmanager_payload": {
102
+ "receiver": "omd-servicenow-webhook",
103
+ "status": "firing",
104
+ "alerts": [
105
+ {
106
+ "status": "firing",
107
+ "labels": {
108
+ "alertname": "4490",
109
+ "instance": "4490.example.net",
110
+ "service": "my-service",
111
+ "severity": "critical",
112
+ "snow_service_name": "routemetosvcnow"
113
+ },
114
+ "annotations": {
115
+ "summary": "Testing summary!"
116
+ },
117
+ "startsAt": "2024-03-15T19:51:51.78480206Z",
118
+ "endsAt": "0001-01-01T00:00:00Z",
119
+ "generatorURL": "https://prometheus.local/<generating_expression>",
120
+ "fingerprint": "5de8a3a5c73e68d4"
121
+ }
122
+ ],
123
+ "groupLabels": {
124
+ "alertname": "4490",
125
+ "service": "my-service"
126
+ },
127
+ "commonLabels": {
128
+ "alertname": "4490",
129
+ "instance": "4490.example.net",
130
+ "service": "my-service",
131
+ "severity": "critical",
132
+ "snow_service_name": "routemetosvcnow"
133
+ },
134
+ "commonAnnotations": {
135
+ "summary": "Testing summary!"
136
+ },
137
+ "externalURL": "http://omd-lx01.example.com/alertmanager/alertmanager",
138
+ "version": "4",
139
+ "groupKey": "{}/{alertname=~\"^(?:.*)$\",snow_service_name=~\"^(?:..*)$\"}:{alertname=\"4490\", service=\"my-service\"}",
140
+ "truncatedAlerts": 0
141
+ }
142
+ }
143
+
144
+ amgw = notificationforwarder.baseclass.new("webhook", None, "alertmanager_servicenow", True, True, forwarderopts)
145
+ amgw.forward(eventopts)
146
+
147
+ log = open(get_logfile(amgw)).read()
148
+ assert "event has no node" in log
149
+ assert "replace node with 4490.example.net" in log
150
+ assert "job: " in log
151
+
94
152
  def test_split3_forwarder_split4_formatter_bin_old(setup):
95
153
  # this is used to find out the logfile
96
154
  forwarderopts = {
@@ -123,4 +181,3 @@ def test_split3_forwarder_split4_formatter_bin(setup):
123
181
  log = open(get_logfile(split3)).read()
124
182
  assert "split4_"+signature+"_split4" in log
125
183
 
126
-