dt-extensions-sdk 1.3.1__py3-none-any.whl → 1.4.0__py3-none-any.whl

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dt-extensions-sdk
3
- Version: 1.3.1
3
+ Version: 1.4.0
4
4
  Project-URL: Documentation, https://github.com/dynatrace-extensions/dt-extensions-python-sdk#readme
5
5
  Project-URL: Issues, https://github.com/dynatrace-extensions/dt-extensions-python-sdk/issues
6
6
  Project-URL: Source, https://github.com/dynatrace-extensions/dt-extensions-python-sdk
@@ -1,4 +1,4 @@
1
- dynatrace_extension/__about__.py,sha256=-jEpNU1eRpe8GBW_KoSO-6Flc820P-KhyssXl0K9kO4,110
1
+ dynatrace_extension/__about__.py,sha256=0eF7oFPAs4l6aF4bObZHJnLcIaLQ07bZ0ozH7nzz4HY,110
2
2
  dynatrace_extension/__init__.py,sha256=BvQuknmA7ti3WJi3zEXZfY7aAxJrie37VNitWICsUvI,752
3
3
  dynatrace_extension/cli/__init__.py,sha256=HCboY_eJPoqjFmoPDsBL8Jk6aNvank8K7JpkVrgwzUM,123
4
4
  dynatrace_extension/cli/main.py,sha256=Z8gFcp0vIMBkzV6jUd5mwvP1U0JcLqAHoMLJw_6puz4,18260
@@ -19,7 +19,7 @@ dynatrace_extension/sdk/activation.py,sha256=goTbT1tD2kn8xfyXFdTy_cTZNcFPJpgbvQM
19
19
  dynatrace_extension/sdk/callback.py,sha256=eMpC0F3fCI82mWHIFgmy9QmKl7Kq_9dSaanHdV6o7hA,6511
20
20
  dynatrace_extension/sdk/communication.py,sha256=QkJgEBblOen-jmvsb3ZfYZYglYUc7jHbkEgPtRj9l6w,19123
21
21
  dynatrace_extension/sdk/event.py,sha256=J261imbFKpxfuAQ6Nfu3RRcsIQKKivy6fme1nww2g-8,388
22
- dynatrace_extension/sdk/extension.py,sha256=RnF7Czlmg6QrQLLlP90dM0tAIxdX3LrqaUi8M1p1Guo,43251
22
+ dynatrace_extension/sdk/extension.py,sha256=59hg3aUXbrkhvEB7za8jujv1LZQ4sSx4ot9scijadQU,44926
23
23
  dynatrace_extension/sdk/helper.py,sha256=ZNrO9ao2hE3KQ934vAYD74k0fCr6QTG-_bAvbk9-hi8,6562
24
24
  dynatrace_extension/sdk/metric.py,sha256=7VClzJCFJNDCxA-d69uTu1pdPtDZBTwq7fbafs_L6nQ,3690
25
25
  dynatrace_extension/sdk/runtime.py,sha256=jyYsM1x-gMnW68eWq8IoZZZBarHgIcr_nVeGDDgpRDk,2802
@@ -28,8 +28,8 @@ dynatrace_extension/sdk/vendor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5
28
28
  dynatrace_extension/sdk/vendor/mureq/LICENSE,sha256=8AVcgZgiT_mvK1fOofXtRRr2f1dRXS_K21NuxQgP4VM,671
29
29
  dynatrace_extension/sdk/vendor/mureq/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
30
30
  dynatrace_extension/sdk/vendor/mureq/mureq.py,sha256=znF4mvzk5L03CLNozRz8UpK-fMijmSkObDFwlbhwLUg,14656
31
- dt_extensions_sdk-1.3.1.dist-info/METADATA,sha256=LwKOdwizaSteiT3s-yPkAXYRyqkiqQC11TaPXiGlJ-Q,2685
32
- dt_extensions_sdk-1.3.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
33
- dt_extensions_sdk-1.3.1.dist-info/entry_points.txt,sha256=pweyOCgENGHjOlT6_kXYaBPOrE3p18K0UettqnNlnoE,55
34
- dt_extensions_sdk-1.3.1.dist-info/licenses/LICENSE.txt,sha256=3Zihv0lOVYHNfDkJC-tUAU6euP9r2NexsDW4w-zqgVk,1078
35
- dt_extensions_sdk-1.3.1.dist-info/RECORD,,
31
+ dt_extensions_sdk-1.4.0.dist-info/METADATA,sha256=LYTXYtBm33nrBL_jz22oNjpB0mRIhIdr27pFuHgNzao,2685
32
+ dt_extensions_sdk-1.4.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
33
+ dt_extensions_sdk-1.4.0.dist-info/entry_points.txt,sha256=pweyOCgENGHjOlT6_kXYaBPOrE3p18K0UettqnNlnoE,55
34
+ dt_extensions_sdk-1.4.0.dist-info/licenses/LICENSE.txt,sha256=3Zihv0lOVYHNfDkJC-tUAU6euP9r2NexsDW4w-zqgVk,1078
35
+ dt_extensions_sdk-1.4.0.dist-info/RECORD,,
@@ -3,4 +3,4 @@
3
3
  # SPDX-License-Identifier: MIT
4
4
 
5
5
 
6
- __version__ = "1.3.1"
6
+ __version__ = "1.4.0"
@@ -215,6 +215,7 @@ class Extension:
215
215
  "timediff": datetime.now() + TIME_DIFF_INTERVAL,
216
216
  "heartbeat": datetime.now() + HEARTBEAT_INTERVAL,
217
217
  "metrics": datetime.now() + METRIC_SENDING_INTERVAL,
218
+ "events": datetime.now() + METRIC_SENDING_INTERVAL,
218
219
  "sfm_metrics": datetime.now() + SFM_METRIC_SENDING_INTERVAL,
219
220
  }
220
221
 
@@ -227,6 +228,10 @@ class Extension:
227
228
  self._metrics_lock = RLock()
228
229
  self._metrics: List[str] = []
229
230
 
231
+ # Extension logs
232
+ self._logs_lock = RLock()
233
+ self._logs: List[dict] = []
234
+
230
235
  # Self monitoring metrics
231
236
  self._sfm_metrics_lock = Lock()
232
237
  self._callbackSfmReport: Dict[str, WrappedCallback] = {}
@@ -505,6 +510,7 @@ class Extension:
505
510
  properties: Optional[dict] = None,
506
511
  timestamp: Optional[datetime] = None,
507
512
  severity: Union[Severity, str] = Severity.INFO,
513
+ send_immediately: bool = False,
508
514
  ) -> None:
509
515
  """Report an event using log ingest.
510
516
 
@@ -514,6 +520,7 @@ class Extension:
514
520
  properties: A dictionary of extra event properties
515
521
  timestamp: The timestamp of the event, defaults to the current time
516
522
  severity: The severity of the event, defaults to Severity.INFO
523
+ send_immediately: Option to directly schedule log to be sent without batching
517
524
  """
518
525
  if timestamp is None:
519
526
  timestamp = datetime.now(tz=timezone.utc)
@@ -530,7 +537,7 @@ class Extension:
530
537
  **self._metadata,
531
538
  **properties,
532
539
  }
533
- self._send_events(event)
540
+ self._send_events(event, send_immediately=send_immediately)
534
541
 
535
542
  def report_dt_event(
536
543
  self,
@@ -635,7 +642,7 @@ class Extension:
635
642
  raise ValueError(msg)
636
643
  self._send_dt_event(event)
637
644
 
638
- def report_log_event(self, log_event: dict):
645
+ def report_log_event(self, log_event: dict, send_immediately: bool = False):
639
646
  """Report a custom log event using log ingest.
640
647
 
641
648
  Note:
@@ -643,25 +650,28 @@ class Extension:
643
650
 
644
651
  Args:
645
652
  log_event: The log event dictionary.
653
+ send_immediately: Option to directly schedule log to be sent without batching
646
654
  """
647
- self._send_events(log_event)
655
+ self._send_events(log_event, send_immediately=send_immediately)
648
656
 
649
- def report_log_events(self, log_events: List[dict]):
657
+ def report_log_events(self, log_events: List[dict], send_immediately: bool = False):
650
658
  """Report a list of custom log events using log ingest.
651
659
 
652
660
  Args:
653
661
  log_events: The list of log events
662
+ send_immediately: Option to directly schedule log to be sent without batching
654
663
  """
655
- self._send_events(log_events)
664
+ self._send_events(log_events, send_immediately=send_immediately)
656
665
 
657
- def report_log_lines(self, log_lines: List[Union[str, bytes]]):
666
+ def report_log_lines(self, log_lines: List[Union[str, bytes]], send_immediately: bool = False):
658
667
  """Report a list of log lines using log ingest
659
668
 
660
669
  Args:
661
670
  log_lines: The list of log lines
671
+ send_immediately: Option to directly schedule log to be sent without batching
662
672
  """
663
673
  events = [{"content": line} for line in log_lines]
664
- self._send_events(events)
674
+ self._send_events(events, send_immediately=send_immediately)
665
675
 
666
676
  @property
667
677
  def enabled_feature_sets(self) -> dict[str, list[str]]:
@@ -819,6 +829,7 @@ class Extension:
819
829
  for callback in self._scheduled_callbacks_before_run:
820
830
  self._schedule_callback(callback)
821
831
  self._metrics_iteration()
832
+ self._events_iteration()
822
833
  self._sfm_metrics_iteration()
823
834
  self._timediff_iteration()
824
835
  self._scheduler.run()
@@ -838,6 +849,11 @@ class Extension:
838
849
  next_timestamp = self._get_and_set_next_internal_callback_timestamp("metrics", METRIC_SENDING_INTERVAL)
839
850
  self._scheduler.enterabs(next_timestamp, 1, self._metrics_iteration)
840
851
 
852
+ def _events_iteration(self):
853
+ self._internal_executor.submit(self._send_buffered_events)
854
+ next_timestamp = self._get_and_set_next_internal_callback_timestamp("events", METRIC_SENDING_INTERVAL)
855
+ self._scheduler.enterabs(next_timestamp, 1, self._events_iteration)
856
+
841
857
  def _sfm_metrics_iteration(self):
842
858
  self._internal_executor.submit(self._send_sfm_metrics)
843
859
  next_timestamp = self._get_and_set_next_internal_callback_timestamp("sfm_metrics", SFM_METRIC_SENDING_INTERVAL)
@@ -1044,8 +1060,23 @@ class Extension:
1044
1060
  with self._internal_callbacks_results_lock:
1045
1061
  self._internal_callbacks_results[self._send_events.__name__] = Status(StatusValue.GENERIC_ERROR, str(e))
1046
1062
 
1047
- def _send_events(self, events: Union[dict, List[dict]]):
1048
- self._internal_executor.submit(self._send_events_internal, events)
1063
+ def _send_events(self, events: Union[dict, List[dict]], send_immediately: bool = False):
1064
+ if send_immediately:
1065
+ self._internal_executor.submit(self._send_events_internal, events)
1066
+ return
1067
+ with self._logs_lock:
1068
+ if isinstance(events, dict):
1069
+ self._logs.append(events)
1070
+ elif isinstance(events, list):
1071
+ self._logs.extend(events)
1072
+ else:
1073
+ self.logger.error(f"Invalid log format: {events}")
1074
+
1075
+ def _send_buffered_events(self):
1076
+ with self._logs_lock:
1077
+ if len(self._logs) > 0:
1078
+ self._send_events_internal(self._logs)
1079
+ self._logs = []
1049
1080
 
1050
1081
  def _send_dt_event(self, event: dict[str, str | int | dict[str, str]]):
1051
1082
  self._client.send_dt_event(event)