Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 21 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ Django app for storing time-series metrics in Elasticsearch.

python importables:
- `elasticsearch_metrics`
- `elasticsearch_metrics.imps.elastic8`
- `elasticsearch_metrics.imps.elastic6`
- `elasticsearch_metrics.imps.elastic8` (an implementation with elasticsearch 8)
- `elasticsearch_metrics.imps.elastic6` (an implementation with elasticsearch 6; deprecated)
- ...

## Pre-requisites
Expand Down Expand Up @@ -58,7 +58,7 @@ class UsageRecord(EventRecord):
item_id: int

class Index:
using = "my-es8-backend" # optional if only one backend
using = "my-es8-backend" # backend name -- required if multiple backends use the same imp
```

Either enable autosetup...
Expand Down Expand Up @@ -98,19 +98,26 @@ UsageRecord.search_timeseries_range(datetime.date(2030, 1, 1), datetime.date(203

## Timeseries indexes

By default, behind the scenes, a new elasticsearch index is created for each record type for each month
in which a record is saved (using UTC timezone). You can set a default change the per-index timespan by
setting `Meta.timedepth` on the record type.
By default, behind the scenes, a new elasticsearch index is created for each record type for each day
in which a record is saved (using UTC timezone). You can change this for a record type by setting
`Meta.timedepth`, or change the default timedepth with the setting `DJELME_DEFAULT_TIMEDEPTH` (see below).

- index per day, '...YYYY_MM_DD...': `timedepth = 3`
- index per month, '...YYYY_MM...': `timedepth = 2`
- index per year, '...YYYY...': `timedepth = 1`
```python
class MyEventWithMonthlyIndexes(EventRecord):
class Meta:
timedepth = 2 # year and month
```

- index per year: `timedepth = 1`
- index per month: `timedepth = 2`
- index per day: `timedepth = 3` (default)
- index per hour: `timedepth = 4`


## Index settings

You can configure the index template settings by setting
`Index.settings` on a record type.
You can configure the index settings that will be set on the index template
and used for each new timeseries index with `Index.settings` on a record type.

```python
class UsageRecord(EventRecord):
Expand Down Expand Up @@ -166,27 +173,6 @@ class UsageRecord(MyBaseMetric):
app_label = "myapp"
```

## Optional factory_boy integration

```python
import factory
from elasticsearch_metrics.factory import MetricFactory

from ..myapp.metrics import MyMetric


class MyMetricFactory(MetricFactory):
my_int = factory.Faker("pyint")

class Meta:
model = MyMetric


def test_something():
metric = MyMetricFactory() # index metric in ES
assert isinstance(metric.my_int, int)
```

## Configuration

* `DJELME_BACKENDS`: Named backends for storing or searching records from your django app
Expand All @@ -213,9 +199,9 @@ def test_something():
* `DJELME_DEFAULT_TIMEDEPTH`: Set the granularity of timeseries indexes by the number of "time parts" in index names
```
DJELME_DEFAULT_TIMEDEPTH = 1 # yearly indexes; YYYY
DJELME_DEFAULT_TIMEDEPTH = 2 # monthly indexes; YYYY_MM
DJELME_DEFAULT_TIMEDEPTH = 3 # daily indexes; YYYY_MM_DD (this is the default)
DJELME_DEFAULT_TIMEDEPTH = 4 # hourly indexes; YYYY_MM_DD_HH
DJELME_DEFAULT_TIMEDEPTH = 2 # monthly indexes; YYYY.MM
DJELME_DEFAULT_TIMEDEPTH = 3 # daily indexes; YYYY.MM.DD (this is the default)
DJELME_DEFAULT_TIMEDEPTH = 4 # hourly indexes; YYYY.MM.DD.HH
```
you can also set `Meta.timedepth` on a specific record type; this will take precedence

Expand Down
7 changes: 7 additions & 0 deletions elasticsearch_metrics/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,10 @@
"management",
"util",
)

###
# timedepth constants, for when you'd rather think in dates than timedepths
YEARLY = 1
MONTHLY = 2
DAILY = 3
HOURLY = 4
6 changes: 2 additions & 4 deletions elasticsearch_metrics/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ def ready(self) -> None:
)
# autosetup? (default no)
if getattr(settings, AUTOSETUP_SETTING, False) is True:
for (
_backend_name,
_recordtypes,
) in djelme_registry.each_recordtype_by_backend():
_types_by_backend = djelme_registry.recordtypes_by_backend()
for _backend_name, _recordtypes in _types_by_backend.items():
djelme_registry.get_backend(_backend_name).djelme_setup(_recordtypes)
20 changes: 13 additions & 7 deletions elasticsearch_metrics/imps/elastic6.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@ def __new__(mcls, name, bases, attrs): # noqa: B902
# compute it as <app label>_<lowercased class name>
template_name = f"{app_label}_{metric_name}"

new_cls._template_name = template_name
new_cls._template_pattern = f"{template_name}_*" # template pattern
new_cls.__template_name = template_name
new_cls.__template_pattern = f"{template_name}_*" # template pattern
# Abstract base metrics can't be instantiated and don't appear in
# the list of metrics for an app.
if not abstract:
Expand Down Expand Up @@ -135,6 +135,16 @@ def construct_index(cls, opts, bases):
i.analyzer(a)
return i

@property
def _template_name(self):
_prefix = self.get_timeseries_name_prefix()
return f"{_prefix}{self.__template_name}"

@property
def _template_pattern(self):
_prefix = self.get_timeseries_name_prefix()
return f"{_prefix}{self.__template_pattern}"


# We need this intermediate BaseMetric class so that
# we can run MetricMeta ahead of IndexMeta
Expand Down Expand Up @@ -262,10 +272,7 @@ def get_index_name(cls, date: datetime.date | None = None) -> str:
settings, "ELASTICSEARCH_METRICS_DATE_FORMAT", DEFAULT_DATE_FORMAT
)
date_formatted = date.strftime(dateformat)
_name_parts = (cls._template_name, date_formatted)
if _prefix := cls.get_timeseries_name_prefix():
_name_parts = (_prefix, *_name_parts)
return "_".join(_name_parts)
return f"{cls._template_name}_{date_formatted}"


class Metric(Document, BaseMetric):
Expand Down Expand Up @@ -342,7 +349,6 @@ class DjelmeElastic6Backend:

backend_name: str
imp_kwargs: dict[str, str]
namespace_prefix: str = ""

@property
def elastic6_client(self):
Expand Down
Loading
Loading