55import random
66import time
77import zlib
8+ from datetime import datetime
89from functools import wraps , partial
910from threading import Event , Lock , Thread
1011from contextlib import contextmanager
1112
13+ import sentry_sdk
1214from sentry_sdk ._compat import text_type
13- from sentry_sdk .hub import Hub
14- from sentry_sdk .utils import now , nanosecond_time
15+ from sentry_sdk .utils import now , nanosecond_time , to_timestamp
1516from sentry_sdk .envelope import Envelope , Item
1617from sentry_sdk .tracing import (
1718 TRANSACTION_SOURCE_ROUTE ,
2930 from typing import Optional
3031 from typing import Generator
3132 from typing import Tuple
33+ from typing import Union
3234
3335 from sentry_sdk ._types import BucketKey
3436 from sentry_sdk ._types import DurationUnit
@@ -406,14 +408,16 @@ def add(
406408 value , # type: MetricValue
407409 unit , # type: MeasurementUnit
408410 tags , # type: Optional[MetricTags]
409- timestamp = None , # type: Optional[float]
411+ timestamp = None , # type: Optional[Union[ float, datetime] ]
410412 ):
411413 # type: (...) -> None
412414 if not self ._ensure_thread () or self ._flusher is None :
413415 return
414416
415417 if timestamp is None :
416418 timestamp = time .time ()
419+ elif isinstance (timestamp , datetime ):
420+ timestamp = to_timestamp (timestamp )
417421
418422 bucket_timestamp = int (
419423 (timestamp // self .ROLLUP_IN_SECONDS ) * self .ROLLUP_IN_SECONDS
@@ -500,7 +504,7 @@ def _serialize_tags(
500504def _get_aggregator_and_update_tags (key , tags ):
501505 # type: (str, Optional[MetricTags]) -> Tuple[Optional[MetricsAggregator], Optional[MetricTags]]
502506 """Returns the current metrics aggregator if there is one."""
503- hub = Hub .current
507+ hub = sentry_sdk . Hub .current
504508 client = hub .client
505509 if client is None or client .metrics_aggregator is None :
506510 return None , tags
@@ -531,7 +535,7 @@ def incr(
531535 value = 1.0 , # type: float
532536 unit = "none" , # type: MeasurementUnit
533537 tags = None , # type: Optional[MetricTags]
534- timestamp = None , # type: Optional[float]
538+ timestamp = None , # type: Optional[Union[ float, datetime] ]
535539):
536540 # type: (...) -> None
537541 """Increments a counter."""
@@ -545,7 +549,7 @@ def __init__(
545549 self ,
546550 key , # type: str
547551 tags , # type: Optional[MetricTags]
548- timestamp , # type: Optional[float]
552+ timestamp , # type: Optional[Union[ float, datetime] ]
549553 value , # type: Optional[float]
550554 unit , # type: DurationUnit
551555 ):
@@ -597,7 +601,7 @@ def timing(
597601 value = None , # type: Optional[float]
598602 unit = "second" , # type: DurationUnit
599603 tags = None , # type: Optional[MetricTags]
600- timestamp = None , # type: Optional[float]
604+ timestamp = None , # type: Optional[Union[ float, datetime] ]
601605):
602606 # type: (...) -> _Timing
603607 """Emits a distribution with the time it takes to run the given code block.
@@ -620,7 +624,7 @@ def distribution(
620624 value , # type: float
621625 unit = "none" , # type: MeasurementUnit
622626 tags = None , # type: Optional[MetricTags]
623- timestamp = None , # type: Optional[float]
627+ timestamp = None , # type: Optional[Union[ float, datetime] ]
624628):
625629 # type: (...) -> None
626630 """Emits a distribution."""
@@ -634,7 +638,7 @@ def set(
634638 value , # type: MetricValue
635639 unit = "none" , # type: MeasurementUnit
636640 tags = None , # type: Optional[MetricTags]
637- timestamp = None , # type: Optional[float]
641+ timestamp = None , # type: Optional[Union[ float, datetime] ]
638642):
639643 # type: (...) -> None
640644 """Emits a set."""
@@ -648,7 +652,7 @@ def gauge(
648652 value , # type: float
649653 unit = "none" , # type: MetricValue
650654 tags = None , # type: Optional[MetricTags]
651- timestamp = None , # type: Optional[float]
655+ timestamp = None , # type: Optional[Union[ float, datetime] ]
652656):
653657 # type: (...) -> None
654658 """Emits a gauge."""
0 commit comments