omdnotificationforwarder 4.3__tar.gz → 4.4__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 (74) hide show
  1. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/PKG-INFO +1 -1
  2. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/bin/notificationforwarder +1 -1
  3. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/pyproject.toml +1 -1
  4. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/src/notificationforwarder/baseclass.py +9 -1
  5. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/src/notificationforwarder/email/forwarder.py +3 -1
  6. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/src/notificationforwarder/spool.py +28 -18
  7. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/src/notificationforwarder/syslog/forwarder.py +2 -0
  8. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/src/notificationforwarder/telegram/forwarder.py +5 -2
  9. omdnotificationforwarder-4.4/tests/TESTS.md +634 -0
  10. omdnotificationforwarder-4.4/tests/test_contracts_formatters.py +290 -0
  11. omdnotificationforwarder-4.4/tests/test_contracts_forwarders.py +978 -0
  12. omdnotificationforwarder-4.4/tests/test_contracts_reporters.py +249 -0
  13. omdnotificationforwarder-4.4/tests/test_integration_cli.py +102 -0
  14. omdnotificationforwarder-4.4/tests/test_loading_resolution.py +169 -0
  15. omdnotificationforwarder-4.4/tests/test_loggers.py +496 -0
  16. omdnotificationforwarder-4.4/tests/test_nostr.py +701 -0
  17. omdnotificationforwarder-4.4/tests/test_orchestration_flow.py +275 -0
  18. omdnotificationforwarder-4.4/tests/test_resilience_spool.py +871 -0
  19. omdnotificationforwarder-4.3/tests/test_nostr.py +0 -355
  20. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/.gitignore +0 -0
  21. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/README.md +0 -0
  22. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/src/notificationforwarder/component_loader.py +0 -0
  23. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/src/notificationforwarder/email/formatter.py +0 -0
  24. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/src/notificationforwarder/example/formatter.py +0 -0
  25. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/src/notificationforwarder/example/forwarder.py +0 -0
  26. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/src/notificationforwarder/json/__init__.py +0 -0
  27. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/src/notificationforwarder/json/logger.py +0 -0
  28. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/src/notificationforwarder/naemonlog/reporter.py +0 -0
  29. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/src/notificationforwarder/nostr/__init__.py +0 -0
  30. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/src/notificationforwarder/nostr/formatter.py +0 -0
  31. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/src/notificationforwarder/nostr/forwarder.py +0 -0
  32. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/src/notificationforwarder/oauth2webhook/__init__.py +0 -0
  33. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/src/notificationforwarder/oauth2webhook/forwarder.py +0 -0
  34. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/src/notificationforwarder/rabbitmq/formatter.py +0 -0
  35. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/src/notificationforwarder/rabbitmq/forwarder.py +0 -0
  36. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/src/notificationforwarder/runtime_config.py +0 -0
  37. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/src/notificationforwarder/runtime_flow.py +0 -0
  38. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/src/notificationforwarder/syslog/formatter.py +0 -0
  39. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/src/notificationforwarder/text/__init__.py +0 -0
  40. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/src/notificationforwarder/text/logger.py +0 -0
  41. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/src/notificationforwarder/util.py +0 -0
  42. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/src/notificationforwarder/webhook/forwarder.py +0 -0
  43. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/tests/pythonpath/lib/python/notificationforwarder/split1/forwarder.py +0 -0
  44. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/tests/pythonpath/lib/python/notificationforwarder/split2/formatter.py +0 -0
  45. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/tests/pythonpath/lib/python/notificationforwarder/split2/forwarder.py +0 -0
  46. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/tests/pythonpath/lib/python/notificationforwarder/split3/formatter.py +0 -0
  47. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/tests/pythonpath/lib/python/notificationforwarder/split3/forwarder.py +0 -0
  48. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/tests/pythonpath/local/lib/python/notificationforwarder/alertmanager_servicenow/formatter.py +0 -0
  49. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/tests/pythonpath/local/lib/python/notificationforwarder/bayern/formatter.py +0 -0
  50. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/tests/pythonpath/local/lib/python/notificationforwarder/datadup/formatter.py +0 -0
  51. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/tests/pythonpath/local/lib/python/notificationforwarder/datapost/formatter.py +0 -0
  52. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/tests/pythonpath/local/lib/python/notificationforwarder/discard/formatter.py +0 -0
  53. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/tests/pythonpath/local/lib/python/notificationforwarder/split1/formatter.py +0 -0
  54. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/tests/pythonpath/local/lib/python/notificationforwarder/split2/forwarder.py +0 -0
  55. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/tests/pythonpath/local/lib/python/notificationforwarder/split3/formatter.py +0 -0
  56. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/tests/pythonpath/local/lib/python/notificationforwarder/split3/forwarder.py +0 -0
  57. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/tests/pythonpath/local/lib/python/notificationforwarder/split4/formatter.py +0 -0
  58. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/tests/pythonpath/local/lib/python/notificationforwarder/split4/forwarder.py +0 -0
  59. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/tests/pythonpath/local/lib/python/notificationforwarder/ticketsystem/forwarder.py +0 -0
  60. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/tests/pythonpath/local/lib/python/notificationforwarder/ticketsystem/reporter.py +0 -0
  61. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/tests/pythonpath/local/lib/python/notificationforwarder/vong/formatter.py +0 -0
  62. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/tests/test_alertmanager.py +0 -0
  63. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/tests/test_builtin_plugins_focus.py +0 -0
  64. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/tests/test_classes.py +0 -0
  65. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/tests/test_delivery_resilience.py +0 -0
  66. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/tests/test_discard.py +0 -0
  67. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/tests/test_formatter.py +0 -0
  68. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/tests/test_logger.py +0 -0
  69. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/tests/test_oauth2webhook.py +0 -0
  70. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/tests/test_package.py +0 -0
  71. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/tests/test_paths.py +0 -0
  72. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/tests/test_reporter.py +0 -0
  73. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/tests/test_runtime_foundation.py +0 -0
  74. {omdnotificationforwarder-4.3 → omdnotificationforwarder-4.4}/tests/test_webhook.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: omdnotificationforwarder
3
- Version: 4.3
3
+ Version: 4.4
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
@@ -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.3')
81
+ version=f'%(prog)s 4.4')
82
82
 
83
83
  args = parser.parse_args()
84
84
  if not hasattr(args, 'formatter'):
@@ -21,7 +21,7 @@ packages = ["src/notificationforwarder"]
21
21
 
22
22
  [project]
23
23
  name = "omdnotificationforwarder"
24
- version = "4.3"
24
+ version = "4.4"
25
25
  authors = [
26
26
  { name="Gerhard Lausser", email="lausser@yahoo.com" },
27
27
  ]
@@ -415,6 +415,7 @@ class NotificationForwarder(object):
415
415
  with open(self.db_lock_file, "w") as lock_file:
416
416
  locked = self.acquire_lock_with_retry(lock_file)
417
417
  if locked:
418
+ self.baseclass_logs_summary = True
418
419
  try:
419
420
  dropped = self.spool_store.prune_expired(self.max_spool_minutes)
420
421
  replay_attempted = 0
@@ -449,7 +450,14 @@ class NotificationForwarder(object):
449
450
  for id, text in id_events:
450
451
  raw_event = self.spool_store.decode(text)
451
452
  formatted_event = self.format_event(raw_event)
452
- if formatted_event:
453
+ if formatted_event and formatted_event.is_discarded:
454
+ deleted_trash += 1
455
+ logger.info("discard spooled event during replay", {
456
+ 'event_id': id,
457
+ 'action': 'discard_during_replay'
458
+ })
459
+ self.spool_store.delete(id)
460
+ elif formatted_event:
453
461
  replay_attempted += 1
454
462
  try:
455
463
  result = self.submit(formatted_event)
@@ -5,6 +5,8 @@ from email.mime.text import MIMEText
5
5
  from email.mime.multipart import MIMEMultipart
6
6
  from notificationforwarder.baseclass import NotificationForwarder, NotificationFormatter, timeout
7
7
 
8
+ logger = logging.getLogger("notificationforwarder.email")
9
+
8
10
  class EmailForwarder(NotificationForwarder):
9
11
  def __init__(self, opts):
10
12
  super(self.__class__, self).__init__(opts)
@@ -31,6 +33,6 @@ class EmailForwarder(NotificationForwarder):
31
33
  server.quit()
32
34
  return True
33
35
  except Exception as e:
34
- logging.critical("sending mail failed: {}".format(str(e)))
36
+ logger.critical("sending mail failed: {}".format(str(e)))
35
37
  return False
36
38
 
@@ -4,6 +4,7 @@ except ImportError:
4
4
  import json
5
5
  import random
6
6
  import sqlite3
7
+ import threading
7
8
  import time
8
9
  import fcntl
9
10
 
@@ -14,6 +15,7 @@ class SpoolStore:
14
15
  self.table_name = table_name
15
16
  self.connection = None
16
17
  self.cursor = None
18
+ self._lock = threading.Lock()
17
19
 
18
20
  def open(self):
19
21
  self.connection = sqlite3.connect(self.db_file, check_same_thread=False)
@@ -25,45 +27,53 @@ class SpoolStore:
25
27
  payload TEXT NOT NULL,
26
28
  timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL
27
29
  )"""
28
- self.cursor.execute(sql_create)
29
- self.connection.commit()
30
+ with self._lock:
31
+ self.cursor.execute(sql_create)
32
+ self.connection.commit()
30
33
 
31
34
  def count(self):
32
- self.cursor.execute("SELECT COUNT(*) FROM " + self.table_name)
33
- return self.cursor.fetchone()[0]
35
+ with self._lock:
36
+ self.cursor.execute("SELECT COUNT(*) FROM " + self.table_name)
37
+ return self.cursor.fetchone()[0]
34
38
 
35
39
  def enqueue(self, raw_event):
36
40
  sql_insert = "INSERT INTO " + self.table_name + "(payload) VALUES (?)"
37
- self.cursor.execute(sql_insert, (json.dumps(raw_event),))
38
- self.connection.commit()
41
+ with self._lock:
42
+ self.cursor.execute(sql_insert, (json.dumps(raw_event),))
43
+ self.connection.commit()
39
44
 
40
45
  def prune_expired(self, max_spool_minutes):
41
46
  outdated = int(time.time() - 60 * max_spool_minutes)
42
47
  sql_delete = "DELETE FROM " + self.table_name + " WHERE CAST(STRFTIME('%s', timestamp) AS INTEGER) < ?"
43
- self.cursor.execute(sql_delete, (outdated,))
44
- return self.cursor.rowcount
48
+ with self._lock:
49
+ self.cursor.execute(sql_delete, (outdated,))
50
+ return self.cursor.rowcount
45
51
 
46
52
  def fetch_batch(self, limit=10):
47
53
  sql_select = "SELECT id, payload FROM " + self.table_name + " ORDER BY id LIMIT ?"
48
- self.cursor.execute(sql_select, (limit,))
49
- return self.cursor.fetchall()
54
+ with self._lock:
55
+ self.cursor.execute(sql_select, (limit,))
56
+ return self.cursor.fetchall()
50
57
 
51
58
  def delete(self, event_id):
52
- self.cursor.execute("DELETE FROM " + self.table_name + " WHERE id = ?", (event_id,))
53
- self.connection.commit()
59
+ with self._lock:
60
+ self.cursor.execute("DELETE FROM " + self.table_name + " WHERE id = ?", (event_id,))
61
+ self.connection.commit()
54
62
 
55
63
  def decode(self, text):
56
64
  return json.loads(text)
57
65
 
58
66
  def commit(self):
59
- self.connection.commit()
67
+ with self._lock:
68
+ self.connection.commit()
60
69
 
61
70
  def close(self):
62
- if self.cursor:
63
- self.cursor.close()
64
- if self.connection:
65
- self.connection.commit()
66
- self.connection.close()
71
+ with self._lock:
72
+ if self.cursor:
73
+ self.cursor.close()
74
+ if self.connection:
75
+ self.connection.commit()
76
+ self.connection.close()
67
77
 
68
78
 
69
79
  def acquire_lock_with_retry(lock_file, app_logger, max_attempts=3, base_delay=0.1):
@@ -3,6 +3,8 @@ import socket
3
3
  import logging
4
4
  from notificationforwarder.baseclass import NotificationForwarder, NotificationFormatter, timeout
5
5
 
6
+ logger = logging.getLogger("notificationforwarder.syslog")
7
+
6
8
 
7
9
  class SyslogForwarder(NotificationForwarder):
8
10
  def __init__(self, opts):
@@ -1,12 +1,15 @@
1
+ import logging
1
2
  import requests
2
3
  import urllib.parse
3
4
  from notificationforwarder.baseclass import NotificationForwarder, timeout
4
5
 
6
+ logger = logging.getLogger("notificationforwarder.telegram")
7
+
5
8
  class TelegramForwarder(NotificationForwarder):
6
9
  def __init__(self, opts):
7
10
  super(self.__class__, self).__init__(opts)
8
11
  setattr(self, "bot_token", getattr(self, "bot_token", None))
9
- setattr(self, "chat_id", getattr(self, "hat_id", None))
12
+ setattr(self, "chat_id", getattr(self, "chat_id", None))
10
13
 
11
14
  @timeout(30)
12
15
  def submit(self, event):
@@ -33,7 +36,7 @@ class TelegramForwarder(NotificationForwarder):
33
36
  request_params["text"] = urllib.parse.quote(event.payload)
34
37
  request_params["parse_mode"] = "MarkdownV2"
35
38
  request_params["chat_id"] = self.chat_id
36
- response = requests.get("https://api.telegram.org/bot{}/sendMessage".format(self.bot_token), params=request_parms)
39
+ response = requests.get("https://api.telegram.org/bot{}/sendMessage".format(self.bot_token), params=request_params)
37
40
  if response.status_code == requests.codes.ok:
38
41
  logger.info("success: {} result is {}, request was {}".format(event.summary, response.text, request_params))
39
42
  return True