{"id":37072275,"url":"https://github.com/akimrx/yandex-tracker-exporter","last_synced_at":"2026-01-14T08:29:14.812Z","repository":{"id":57748886,"uuid":"523964561","full_name":"akimrx/yandex-tracker-exporter","owner":"akimrx","description":"ETL tool for Yandex.Tracker. Export, transform and load issue metadata, changelog and agile metrics to Clickhouse storage.","archived":false,"fork":false,"pushed_at":"2024-06-09T06:31:03.000Z","size":996,"stargazers_count":35,"open_issues_count":0,"forks_count":4,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-09-21T20:02:03.839Z","etag":null,"topics":["agile","cycle-time","etl","time-to-market","tracker","yandex","yandex-tracker"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/akimrx.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-08-12T05:21:48.000Z","updated_at":"2025-04-22T12:38:34.000Z","dependencies_parsed_at":"2022-08-27T00:20:27.670Z","dependency_job_id":"a525e1ec-88da-42d7-8393-3552e628edfe","html_url":"https://github.com/akimrx/yandex-tracker-exporter","commit_stats":{"total_commits":4,"total_committers":1,"mean_commits":4.0,"dds":0.0,"last_synced_commit":"220c378cd3154f3f11a6c76580069181f13a133a"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/akimrx/yandex-tracker-exporter","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akimrx%2Fyandex-tracker-exporter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akimrx%2Fyandex-tracker-exporter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akimrx%2Fyandex-tracker-exporter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akimrx%2Fyandex-tracker-exporter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/akimrx","download_url":"https://codeload.github.com/akimrx/yandex-tracker-exporter/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akimrx%2Fyandex-tracker-exporter/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28414036,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T08:16:59.381Z","status":"ssl_error","status_checked_at":"2026-01-14T08:13:45.490Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agile","cycle-time","etl","time-to-market","tracker","yandex","yandex-tracker"],"created_at":"2026-01-14T08:29:13.957Z","updated_at":"2026-01-14T08:29:14.798Z","avatar_url":"https://github.com/akimrx.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/tracker-exporter.svg)](https://pypi.org/project/tracker-exporter/)\n[![PyPi Package](https://img.shields.io/pypi/v/tracker-exporter.svg)](https://pypi.org/project/tracker-exporter/)\n[![Tests](https://github.com/akimrx/yandex-tracker-exporter/workflows/Tests/badge.svg)](https://github.com/akimrx/yandex-tracker-exporter)\n\n# Yandex.Tracker ETL\n\nExport issue metadata \u0026 agile metrics, transform and load to OLAP data storage. Metrics based on issue changelog.\n\n⚠️ **Important**  \n**Versions 1.x.x incompatible with 0.1.x. New versions works only on Python \u003e= 3.10**\n\n\u003e You can fork this repository and refine the tool the way you want. Or use it as it is - this will allow you to build basic analytics on the tasks from Yandex.Tracker.\n\n**Require:**\n\n- Python `\u003e=3.10.*`\n- Clickhouse + specific [tables](/migrations/clickhouse/) (how to run [migration](#migration))\n\n**Collects:**\n\n- Issue metadata (i.e. title, author, assignee, components, tags, status, etc)\n- Issue changelog (i.e the history of all the events that occurred with the task)\n- Calculated issue metrics by status (i.e. the time spent in a particular status) like Cycle \u0026 Lead time\n\n## Datalens Demo\n\n**[Deploy this demo dashboard to your Datalens instance](https://datalens.yandex.ru/marketplace/f2ejcgrg2h910r7cc93u)**\n\n## What does this tool do?\n\n**ETL** – Export, transform, load.\n\nIt's simple. It doesn't do anything supernatural, it doesn't have Rocket Science in it.  \nThis is a simple ant with some mathematical abilities that takes data from one place, sorts/transforms/adapts/calculate them and puts them in another place.  \nSometimes he has to go to a lot of endpoints to collect what needs to be taken to the storage (that's the way Yandex.Tracker API).\n\n**Important.**\n\nBy default, the exporter processes only those tasks that were changed during the sliding window specified in the `EXPORTER_TRACKER__SEARCH__RANGE` parameter.  \nSo, all tasks that have activity (changes) will be uploaded to the storage. Something like eventual consistency.\n\nIf you need to upload historical data that will never be updated again, you can flexibly control behavior through the [environment variables described below](#general-settings).\n\nHere are some recipes for a one-shot export:\n\n1. Launch a exporter with the parameter `EXPORTER_TRACKER__SEARCH__RANGE`, for example, a year ago\n2. More specifically: describe the query in the tracker's QL format using the `EXPORTER_TRACKER__SEARCH__QUERY` environment variable. This way you can export point bundles of tasks and bypass with the [Tracker's strict limit of 10,000 tasks](https://github.com/yandex/yandex_tracker_client/issues/13).\n\nFinally run exporter with `--run-once` flag.\n\n### Stateful mode\n\nBy default, the exporter does not store the state, and as described above, it works within the sliding window. This behavior is not the most optimal, because the exporter performs repeated processing for previous tasks.\n\nThe behavior can be changed by enabling stateful mode, which supports 3 backends:\n\n- Local JSON file\n- Remote JSON file (S3 object storage)\n- Redis\n\n#### Local JSON file\n\n```ini\nEXPORTER_STATEFUL=true\n\n# used for the first run to capture historical issues\n# when the previous state is not exists.\nEXPORTER_STATEFUL_INITIAL_RANGE=7d  # this is default value\n\nEXPORTER_STATE__STORAGE=jsonfile  # this is default value\nEXPORTER_STATE__JSONFILE_STRATEGY=local  # this is default value\n\n...\n```\n\n#### Remote JSON file (S3)\n\n```ini\nEXPORTER_STATEFUL=true\nEXPORTER_STATEFUL_INITIAL_RANGE=7d\n\nEXPORTER_STATE__STORAGE=jsonfile\nEXPORTER_STATE__JSONFILE_STRATEGY=s3\n\nEXPORTER_STATE__JSONFILE_S3_BUCKET=tracker-exporter-state\nEXPORTER_STATE__JSONFILE_S3_ACCESS_KEY=YCAxxxxxxxx\nEXPORTER_STATE__JSONFILE_S3_SECRET_KEY=YCxxx-xxxxxxxxxxxxxxx\nEXPORTER_STATE__JSONFILE_S3_ENDPOINT=https://storage.yandexcloud.net\n\n...\n```\n\n#### Redis\n\n```ini\n\nEXPORTER_STATEFUL=true\nEXPORTER_STATEFUL_INITIAL_RANGE=7d\n\nEXPORTER_STATE__STORAGE=redis\nEXPORTER_STATE__REDIS_DSN=redis://localhost:6379\n\n...\n```\n\n### Cycle time calculation algorithm\n\nCurrently, status metrics are calculated based on the transition between statuses (using a issue changelog). The counting algorithm will be improved.\n\nLet's imagine that the task can be, for example, only in 5 statuses:\n\n- Open\n- In progress\n- Testing\n- Ready for release\n- Closed\n\nEmployees start working on the task, the history of the task and the actions of employees is described below, with a correlation to the work of the exporter.\n\n1. A new task has created with the initial status `Open`, metrics are not counted.\n2. The developer has taken the task to work, the transition is `Open -\u003e In progress`, the metric for the `Open` status has been calculated, while the current status `In progress` is not yet considered.\n3. The developer has submitted the task to testing, the transition `In progress -\u003e Testing`, the metric for the status `In progress` has been calculated, while the current status is being `Testing` is not yet considered.\n4. QA Engineer returned the task for revision, the transition `Testing -\u003e In progress`, the time in the status `Testing` has been calculated, the status `In progress` has the previous metric and has not changed yet.\n5. The task has been finalized, re-submitted to testing, the transition `In progress -\u003e Testing`, the delta of this transition is added incrementally to the previous value of the metric `In progress`, but `Testing` has not changed yet.\n   6 The task has been tested and submitted for release, the transition `Testing -\u003e Ready for release`, the delta of this transition is incrementally added to the previous value of the metric `Testing`, the `Ready for Release` status is not considered yet.\n6. The release is completed, the task is closed, the transition `Ready for release -\u003e Closed`, the metric for the `Ready for Release` status is considered. **The metric of the final status of this task (`Closed`) will not be (re)calculated.**\n\n#### Planned improvements\n\nConsider the status metric if a transition has been made to it, even if such a status is current and the next transition has not yet been made from it. Exclude the final statuses from the innovation.\n\n## Tech stats\n\n\u003e Metrics based on 100,000+ constantly changing production issues\n\n- **CPU usage**: from `2%` to `10%`\n- **Memory usage (RSS):** from `48MB` to `256MB`\n- **Average processing time per issue (metrics + issue metadata)**: 1.5 seconds\n- **Average processing time per issue (with full changelog export):** 7 seconds\n\n### Why is it taking so long?\n\nThis is how the tracker API and the library I use work. To get additional information about the task, you need to make a subquery in the API. For example, get the status name, employee name, and so on. When collecting data about a single task, more than several dozen HTTP requests can be executed.\n\nThis is also the answer to the question why the tool is not asynchronous. Limits in the API would not allow effective use of concurrency.\n\nThe processing speed of one issue depends on how many changes there are in the issue in its history. More changes means longer processing.\n\n## Extend exported issue data by your custom fields\n\nJust declare your `main.py` module in which extended the [TrackerIssue](tracker_exporter/models/issue.py#L65) model like:\n\n```python\n\nfrom tracker_exporter.models.issue import TrackerIssue\nfrom tracker_exporter.utils.helpers import validate_resource\nfrom tracker_exporter import run_etl\n\n\nclass ExtendedTrackerIssue(TrackerIssue):\n    def __init__(self, issue: Issues) -\u003e None:\n        super().__init__(issue)\n\n        self.foo_custom_field = validate_resource(issue, \"fooCustomField\")\n        self.bar_custom_field = validate_resource(issue, \"barCustomField\")\n\n\nrun_etl(issue_model=ExtendedTrackerIssue)\n\n```\n\n**Don't forget about adding fields to the Clickhouse migration.**\n\nSee full example with mixin [here](examples/extended_model/main.py)\n\n## Usage\n\n### Native\n\n#### Install from source\n\n```bash\n# prepare virtual environment\npython3 -m venv venv\nsource venv/bin/activate\nmake install\n\n# configure environment variables\nexport EXPORTER_TRACKER__TOKEN=your_oauth_token  # or EXPORTER_TRACKER__IAM_TOKEN\nexport EXPORTER_TRACKER__CLOUD_ORG_ID=your_cloud_org_id  # or EXPORTER_TRACKER__ORG_ID for yandex360\nexport EXPORTER_CLICKHOUSE__HOST=localhost\nexport EXPORTER_CLICKHOUSE__PORT=8123\nexport EXPORTER_CLICKHOUSE__USERNAME=agile\nexport EXPORTER_CLICKHOUSE__PASSWORD=agile\n\n\n# run\ntracker-exporter\n```\n\n#### Install from PyPI\n\n```bash\npip3 install tracker-exporter\ntracker-exporter\n```\n\n#### Configure via .env file\n\nRead about the settings [here](#environment-variables-settings)\n\n```bash\ntracker-exporter --env-file /home/akimrx/tracker/.settings\n```\n\n### Docker\n\n```bash\n\ncd yandex-tracker-exporter\ndocker-compose up -d --build\n\n# Run clickhouse migrations\n\ndocker logs tracker-exporter -f\n```\n\n## On-premise arch example\n\n![](/docs/images/agile_metrics.png)\n\n### On-premise Clickhouse\n\nSo, you can install Clickhouse with Proxy via [Ansible role inside project (previous versions)](https://github.com/akimrx/yandex-tracker-exporter/tree/v0.1.19/ansible).  \nEdit the inventory file `ansible/inventory/hosts.yml` and just run ansible-playbook.\n\n\u003e **Attention:**\n\u003e For the role to work correctly, docker must be installed on the target server.\n\nExample Clickhouse installation:\n\n```bash\ngit clone https://github.com/akimrx/yandex-tracker-exporter.git\ncd yandex-tracker-exporter\ngit checkout v0.1.19\npython3 -m venv venv \u0026\u0026 source venv/bin/activate\npip3 install -r requirements-dev.txt\ncd ansible\nansible-playbook -i inventory/hosts.yml playbooks/clickhouse.yml --limit agile\n```\n\nAlso, you can use [this extended Clickhouse role](https://github.com/akimrx/ansible-clickhouse-role)\n\n## Yandex.Cloud – Cloud Functions\n\n![](/docs/images/agile_metrics_cloud.png)\n\n### Create a Managed Clickhouse cluster\n\n\u003e How to: https://cloud.yandex.com/en/docs/managed-clickhouse/operations/cluster-create\n\n- Set user for exporter, example: `agile`\n- Set a database name, example: `agile`\n- Enable `Serverless access` flag\n- For testing enable host public access\n- Enable `Access from the management console` flag\n- Run migration or manual create tables (see migration block [here](#migration), see [sql](/migrations/clickhouse/))\n\n### Create Cloud Function\n\n\u003e How to: https://cloud.yandex.com/en/docs/functions/quickstart/create-function/python-function-quickstart\n\n- Use Python \u003e= 3.10\n- Copy/paste example content from `examples/serverless` ([code](/examples/serverless/))\n- Set entrypoint: `main.handler` (for code from examples)\n- Set function timeout to `600`, because the launch can be long if there are a lot of updated issues during the collection period\n- Set memory to `512MB` or more\n- Add environment variables (see variables block [here](#configuration-via-environment-variables))\n\n```ini\nEXPORTER_TRACKER__TOKEN=XXXXXXXXXXXXXXXX\nEXPORTER_TRACKER__CLOUD_ORG_ID=123456\nEXPORTER_TRACKER__SEARCH__RANGE=2h\nEXPORTER_CLICKHOUSE__ENABLE_UPLOAD=\"true\"\nEXPORTER_CLICKHOUSE__PROTO=https\nEXPORTER_CLICKHOUSE__CACERT_PATH=/etc/ssl/certs/ca-certificates.crt\nEXPORTER_CLICKHOUSE__PORT=8443\nEXPORTER_CLICKHOUSE__HOST=rc1b-xxxxxx.mdb.yandexcloud.net\nEXPORTER_CLICKHOUSE__USERNAME=agile\nEXPORTER_CLICKHOUSE__PASSWORD=xxxx\nEXPORTER_CHANGELOG_EXPORT_ENABLED=\"false\"\n```\n\n- Release function\n- Run test\n- See logs\n\n![](/docs/images/logs.png)\n\n##### Serverless database connection without public access\n\nIf you don't want to enable clickhouse public access, use service account with such permissions - `serverless.mdbProxies.user` and set environment variables below:\n\n```bash\nEXPORTER_CLICKHOUSE__HOST=akfd3bhqk3xxxxxxxxxxx.clickhouse-proxy.serverless.yandexcloud.net\nEXPORTER_CLICKHOUSE__SERVERLESS_PROXY_ID=akfd3bhqk3xxxxxxxxxxxxx\n```\n\n\u003e How to create database connection: https://cloud.yandex.com/en/docs/functions/operations/database-connection\n\nAlso, the `EXPORTER_CLICKHOUSE__PASSWORD` variable with service account must be replaced by IAM-token. Keep this in mind.\nProbably, you should get it in the function code, because the IAM-token works for a limited period of time.\n\n### Create Trigger\n\n\u003e How to: https://cloud.yandex.com/en/docs/functions/quickstart/create-trigger/timer-quickstart\n\n- Create new trigger\n- Choose type `Timer`\n- Set interval every hour: `0 * ? * * *`\n- Select your function\n- Create serverless service account or use an existing one\n- Save trigger\n\n# Visualization\n\nYou can use any BI/observability tool for visualization, for example:\n\n- Yandex DataLens (btw, this is [opensource](https://github.com/datalens-tech/datalens)). Also see [demo set](https://datalens.yandex.ru/marketplace/f2ejcgrg2h910r7cc93u)\n- Apache Superset\n- PowerBI\n- Grafana\n\n![](/docs/images/datalens_example.png)\n\n# Migration\n\nBased on [go-migrate](https://github.com/golang-migrate/migrate) tool.\n\n## Download and install go-migrate tool\n\n### macOS\n\n```shell\nwget https://github.com/golang-migrate/migrate/releases/download/v4.15.2/migrate.darwin-amd64.tar.gz -O migrate.tar.gz\n\ntar xvf migrate.tar.gz\nmv migrate ~/bin\n```\n\n### Linux\n\n```shell\nwget https://github.com/golang-migrate/migrate/releases/download/v4.15.2/migrate.linux-amd64.tar.gz -O migrate.tar.gz\n\ntar -xvf migrate.tar.gz\nmv migrate /usr/local/bin\n```\n\n## Run migration\n\nExample bash script below.  \nSee full example script [here](/data-migrate.sh)\n\n```bash\n#!/usr/bin/env bash\n\nset -Eeuo pipefail\n\nCLICKHOUSE_HOST=\"localhost\"\nCLICKHOUSE_TCP_PORT=9000\nCLICKHOUSE_HTTP_PORT=8123\nCLICKHOUSE_USER=\"default\"\nCLICKHOUSE_PASSWORD=\"strongpassword\"\n\nMIGRATION_SOURCE_PATH=\"file://${PWD}/../migrations/clickhouse\"\nMIGRATION_HISTORY_TABLE=\"ci_gomigrate_migrations\"\nMIGRATION_DATABASE=\"agile\"\n\nMIGRATION_CLICKHOUSE_DSN=\"clickhouse://${CLICKHOUSE_HOST}:${CLICKHOUSE_TCP_PORT}?username=${CLICKHOUSE_USER}\u0026password=${CLICKHOUSE_PASSWORD}\u0026database=${MIGRATION_DATABASE}\u0026x-multi-statement=true\u0026x-migrations-table=${MIGRATION_HISTORY_TABLE}\"\n\nprepare_migration() {\n    echo \"CREATE DATABASE IF NOT EXISTS ${MIGRATION_DATABASE}\" | \\\n        curl \"http://${CLICKHOUSE_HOST}:${CLICKHOUSE_HTTP_PORT}/?user=${CLICKHOUSE_USER}\u0026password=${CLICKHOUSE_PASSWORD}\" --data-binary @-\n\n}\n\nrun_migration() {\n    migrate -verbose \\\n        -source $MIGRATION_SOURCE_PATH \\\n        -database $MIGRATION_CLICKHOUSE_DSN \\\n        up\n\n}\n\nprepare_migration\nrun_migration\n```\n\n# Configuration via environment variables\n\nSee config declaration [here](/tracker_exporter/config.py)\n\n## General settings\n\n| variable                              | description                                                                                                        |\n| ------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |\n| `EXPORTER_STATEFUL`                   | Enable stateful mode. Required `EXPORTER_STATE__*` params. Default is `False`                                      |\n| `EXPORTER_STATEFUL_INITIAL_RANGE`     | Initial search range when unknown last state. Default: `1w`                                                        |\n| `EXPORTER_CHANGELOG_EXPORT_ENABLED`   | Enable export all issues changelog to Clickhouse. **Can greatly slow down exports** (x5 - x10). Default is `False` |\n| `EXPORTER_LOGLEVEL`                   | ETL log level. Default: `info`                                                                                     |\n| `EXPORTER_LOG_ETL_STATS`              | Enable logging transform stats every N iteration. Default is `True`                                                |\n| `EXPORTER_LOG_ETL_STATS_EACH_N_ITER`  | How many iterations must pass to log stats. Default is `100`                                                       |\n| `EXPORTER_WORKDAYS`                   | Workdays for calculate business time. 0 - mon, 6 - sun. Default: `[0,1,2,3,4]`                                     |\n| `EXPORTER_BUSINESS_HOURS_START`       | Business hours start for calculate business time. Default: `09:00:00`                                              |\n| `EXPORTER_BUSINESS_HOURS_END`         | Business hours end for calculate business time. Default: `22:00:00`                                                |\n| `EXPORTER_DATETIME_RESPONSE_FORMAT`   | Yandex.Tracker datetime format in responses. Default: `%Y-%m-%dT%H:%M:%S.%f%z`                                     |\n| `EXPORTER_DATETIME_QUERY_FORMAT`      | Datetime format for search queries. Default: `%Y-%m-%d %H:%M:%S`                                                   |\n| `EXPORTER_DATETIME_CLICKHOUSE_FORMAT` | Datetime format for Clickhouse. Default: `%Y-%m-%dT%H:%M:%S.%f`                                                    |\n| `EXPORTER_ETL_INTERVAL_MINUTES`       | Interval between run ETL. Default: `30` (minutes)                                                                  |\n| `EXPORTER_CLOSED_ISSUE_STATUSES`      | Statuses for mark issue as closed. Default: `closed,rejected,resolved,cancelled,released`                          |\n| `EXPORTER_NOT_NULLABLE_FIELDS`        | Fields that should never be null (e.g. dates). Default: all datetime fields                                        |\n\n## Tracker settings\n\n| variable                                   | description                                                                                                                    |\n| ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------ |\n| `EXPORTER_TRACKER__LOGLEVEL`               | Log level for Yandex.Tracker SDK. Default: `warning`                                                                           |\n| `EXPORTER_TRACKER__TOKEN`                  | OAuth2 token. Required if `EXPORTER_TRACKER__IAM_TOKEN` is not passed                                                          |\n| `EXPORTER_TRACKER__ORG_ID`                 | Yandex360 organization ID. Required if `EXPORTER_TRACKER__CLOUD_ORG_ID` is not passed                                          |\n| `EXPORTER_TRACKER__IAM_TOKEN`              | Yandex.Cloud IAM token. Required if `EXPORTER_TRACKER__TOKEN` is not passed                                                    |\n| `EXPORTER_TRACKER__CLOUD_ORG_ID`           | Yandex.Cloud organization ID. Required if `EXPORTER_TRACKER__ORG_ID` is not passed                                             |\n| `EXPORTER_TRACKER__TIMEOUT`                | Yandex.Tracker HTTP requests timeout. Default: `10` (sec)                                                                      |\n| `EXPORTER_TRACKER__MAX_RETRIES`            | Yandex.Tracker HTTP requests max retries. Default: `10`                                                                        |\n| `EXPORTER_TRACKER__LANGUAGE`               | Yandex.Tracker language. Default: `en`                                                                                         |\n| `EXPORTER_TRACKER__TIMEZONE`               | Yandex.Tracker timezone. Default: `Europe/Moscow`                                                                              |\n| `EXPORTER_TRACKER__SEARCH__QUERY`          | Custom query for search issues. This variable has the highest priority and overrides other search parameters. Default is empty |\n| `EXPORTER_TRACKER__SEARCH__RANGE`          | Search issues window. Has no effect in stateful mode. Default: `2h`                                                            |\n| `EXPORTER_TRACKER__SEARCH__QUEUES`         | Include or exclude queues in search. Example: `DEV,SRE,!TEST,!TRASH` Default is empty (i.e. all queues)                        |\n| `EXPORTER_TRACKER__SEARCH__PER_PAGE_LIMIT` | Search results per page. Default: `100`                                                                                        |\n\n## Clickhouse settings\n\n| variable                                      | description                                                        |\n| --------------------------------------------- | ------------------------------------------------------------------ |\n| `EXPORTER_CLICKHOUSE__ENABLE_UPLOAD`          | Enable upload data to Clickhouse. Default is `True`                |\n| `EXPORTER_CLICKHOUSE__HOST`                   | Clickhouse host. Default: `localhost`                              |\n| `EXPORTER_CLICKHOUSE__PROTO`                  | Clickhouse protocol: http or https. Default: `http`                |\n| `EXPORTER_CLICKHOUSE__PORT`                   | Clickhouse HTTP(S) port. Default: `8123`                           |\n| `EXPORTER_CLICKHOUSE__CACERT_PATH`            | Path to CA cert. Only for HTTPS proto. Default is empty            |\n| `EXPORTER_CLICKHOUSE__SERVERLESS_PROXY_ID`    | Yandex Cloud Functions proxy ID. Default is empty                  |\n| `EXPORTER_CLICKHOUSE__USERNAME`               | Clickhouse username. Default: `default`                            |\n| `EXPORTER_CLICKHOUSE__PASSWORD`               | Clickhouse password. Can be empty. Default is empty                |\n| `EXPORTER_CLICKHOUSE__DATABASE`               | Clickhouse database. Default: `agile`                              |\n| `EXPORTER_CLICKHOUSE__ISSUES_TABLE`           | Clickhouse table for issues metadata. Default: `issues`            |\n| `EXPORTER_CLICKHOUSE__ISSUE_METRICS_TABLE`    | Clickhouse table for issue metrics. Default: `issue_metrics`       |\n| `EXPORTER_CLICKHOUSE__ISSUES_CHANGELOG_TABLE` | Clickhouse table for issues changelog. Default: `issues_changelog` |\n| `EXPORTER_CLICKHOUSE__AUTO_DEDUPLICATE`       | Execute `OPTIMIZE` after each `INSERT`. Default is `True`          |\n| `EXPORTER_CLICKHOUSE__BACKOFF_BASE_DELAY`     | Base delay for backoff strategy. Default: `0.5` (sec)              |\n| `EXPORTER_CLICKHOUSE__BACKOFF_EXPO_FACTOR`    | Exponential factor for multiply every try. Default: `2.5` (sec)    |\n| `EXPORTER_CLICKHOUSE__BACKOFF_MAX_TRIES`      | Max tries for backoff strategy. Default: `3`                       |\n| `EXPORTER_CLICKHOUSE__BACKOFF_JITTER`         | Enable jitter (randomize delay) for retries. Default: `True`       |\n\n## State settings\n\n| variable                                 | description                                                                               |\n| ---------------------------------------- | ----------------------------------------------------------------------------------------- |\n| `EXPORTER_STATE__STORAGE`                | Storage type for StateKeeper. Can be: `jsonfile`, `redis`, `custom`. Default: `jsonfile`  |\n| `EXPORTER_STATE__REDIS_DSN`              | Connection string for Redis state storage when storage type is `redis`. Default is empty. |\n| `EXPORTER_STATE__JSONFILE_STRATEGY`      | File store strategy for `jsonfile` storage type. Can be `s3` or `local`. Default: `local` |\n| `EXPORTER_STATE__JSONFILE_PATH`          | Path to JSON state file. Default: `./state.json`                                          |\n| `EXPORTER_STATE__JSONFILE_S3_BUCKET`     | Bucket for `s3` strategy. Default is empty                                                |\n| `EXPORTER_STATE__JSONFILE_S3_REGION`     | Region for `s3` strategy. Default is `us-east-1`                                          |\n| `EXPORTER_STATE__JSONFILE_S3_ENDPOINT`   | Endpoint URL for `s3` strategy. Default is empty                                          |\n| `EXPORTER_STATE__JSONFILE_S3_ACCESS_KEY` | AWS access key id for `s3` strategy. Default is empty                                     |\n| `EXPORTER_STATE__JSONFILE_S3_SECRET_KEY` | AWS secret key for `s3` strategy. Default is empty                                        |\n| `EXPORTER_STATE__CUSTOM_STORAGE_PARAMS`  | Settings for custom storage params as `dict`. Default: `{}`                               |\n\n## Observability settings\n\n| variable                                   | description                                                                  |\n| ------------------------------------------ | ---------------------------------------------------------------------------- |\n| `EXPORTER_MONITORING__METRICS_ENABLED`     | Enable send statsd tagged metrics. Default is `False`                        |\n| `EXPORTER_MONITORING__METRICS_HOST`        | DogStatsD / statsd host. Default: `localhost`                                |\n| `EXPORTER_MONITORING__METRICS_PORT`        | DogStatsD / statsd port. Default: `8125`                                     |\n| `EXPORTER_MONITORING__METRICS_BASE_PREFIX` | Prefix for metrics name. Default: `tracker_exporter`                         |\n| `EXPORTER_MONITORING__METRICS_BASE_LABELS` | List of tags for metrics. Example: `[\"project:internal\",]`. Default is empty |\n| `EXPORTER_MONITORING__SENTRY_ENABLED`      | Enable send exception stacktrace to Sentry. Default is `False`               |\n| `EXPORTER_MONITORING__SENTRY_DSN`          | Sentry DSN. Default is empty                                                 |\n\n# Monitoring\n\nBased on DogStatsD tagged format. VictoriaMetrics compatible.\n\n| Metric name                                            | Metric type | Labels          | Description                                                |\n| ------------------------------------------------------ | ----------- | --------------- | ---------------------------------------------------------- |\n| `tracker_exporter_issue_transform_time_seconds`        | time        | -               | Duration of transform per task (data packing to the model) |\n| `tracker_exporter_issues_total_processed_count`        | count       | -               | Total issues processed                                     |\n| `tracker_exporter_issues_search_time_seconds`          | time        | -               | Yandex.Tracker search duration time in seconds             |\n| `tracker_exporter_issues_without_metrics`              | count       | -               | Issues with empty metrics (no changelog)                   |\n| `tracker_exporter_issue_prefetch_seconds`              | time        | -               | Pre-transform data duration in seconds                     |\n| `tracker_exporter_comments_fetch_seconds`              | time        | -               | Comments fetch duration in seconds                         |\n| `tracker_exporter_etl_duration_seconds`                | time        | -               | ETL full pipeline duration in seconds                      |\n| `tracker_exporter_etl_upload_status`                   | gauge       | -               | Last upload status, 1 - success, 2 - fail                  |\n| `tracker_exporter_export_and_transform_time_seconds`   | time        | -               | Overall export and transform duration in seconds           |\n| `tracker_exporter_upload_to_storage_time_seconds`      | time        | -               | Overall insert duration time in seconds                    |\n| `tracker_exporter_last_update_timestamp`               | gauge       | -               | Last data update timestamp                                 |\n| `tracker_exporter_clickhouse_insert_time_seconds`      | time        | database, table | Insert per table duration time in seconds                  |\n| `tracker_exporter_clickhouse_inserted_rows`            | count       | database, table | Inserted rows per table                                    |\n| `tracker_exporter_clickhouse_deduplicate_time_seconds` | time        | database, table | Optimize execute time duration in seconds                  |\n\n### Metrics on dashboard demo\n\n![](/docs/images/etl_metrics.jpeg)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fakimrx%2Fyandex-tracker-exporter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fakimrx%2Fyandex-tracker-exporter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fakimrx%2Fyandex-tracker-exporter/lists"}