From 8736d2a916acdb3f975c23711d62716585107e86 Mon Sep 17 00:00:00 2001 From: Melinda Fekete Date: Tue, 8 Oct 2024 12:11:05 +0200 Subject: [PATCH] Events docs revamp (#8360) --- .../django/django-examples.md | 8 +- .../dotnet/dotnet-examples.md | 8 +- .../feature-flag-tutorials/ios/examples.md | 8 +- .../java/spring-boot-examples.md | 6 +- .../feature-flag-tutorials/python/examples.md | 8 +- .../rails/rails-examples.md | 8 +- .../feature-flag-tutorials/react/examples.md | 8 +- .../ruby/ruby-examples.md | 8 +- .../rust/rust-examples.md | 8 +- .../use-cases/gradual-rollout.md | 4 +- .../docs/how-to/how-to-use-the-admin-api.md | 4 +- website/docs/reference/actions.md | 2 +- .../reference/api-tokens-and-client-keys.mdx | 2 +- .../api/legacy/unleash/admin/events.md | 4 +- website/docs/reference/event-log.md | 21 - website/docs/reference/event-types.mdx | 1472 ----------------- website/docs/reference/events.mdx | 725 ++++++++ .../docs/reference/integrations/datadog.md | 2 +- website/docs/reference/service-accounts.md | 2 +- website/docusaurus.config.js | 14 +- website/sidebars.js | 3 +- website/static/img/event-timeline.png | Bin 0 -> 63440 bytes website/vercel.json | 12 +- 23 files changed, 793 insertions(+), 1544 deletions(-) delete mode 100644 website/docs/reference/event-log.md delete mode 100644 website/docs/reference/event-types.mdx create mode 100644 website/docs/reference/events.mdx create mode 100644 website/static/img/event-timeline.png diff --git a/website/docs/feature-flag-tutorials/django/django-examples.md b/website/docs/feature-flag-tutorials/django/django-examples.md index 34debb792b..5bf0fc8fd5 100644 --- a/website/docs/feature-flag-tutorials/django/django-examples.md +++ b/website/docs/feature-flag-tutorials/django/django-examples.md @@ -348,15 +348,15 @@ Because a feature flag service controls how an application behaves in production Unleash provides the data to log any change over time at the flag level and at the project level. Logs are useful for downstream data warehouses or data lakes. Tools like [Splunk](https://www.splunk.com/) can help you combine logs and run advanced queries against them. -For our Python app, we can view Event logs to monitor the changes to flag strategies and statuses we have made throughout our examples, such as: +For our Python app, we can view events in [Event Log](/reference/events#event-log) to monitor the changes to flag strategies and statuses we have made throughout our examples, such as: - When the flag was created - How the gradual rollout strategy was configured - When and how the variants were created and configured -![Event logs in Unleash track every single change made to flags, similar to Git commit history.](/img/python-ex-logs.png) +![Event Log in Unleash tracks every single change made to flags, similar to Git commit history.](/img/python-ex-logs.png) -You can also retrieve event log data by using an API command below: +You can also retrieve events by using an API command below: ```py import requests @@ -374,7 +374,7 @@ response = requests.request("GET", url, headers=headers, data=payload) print(response.text) ``` -Read our documentation on [Event logs](/reference/event-log) and [APIs](/reference/api/unleash/get-events-for-toggle) to learn more. +Read our documentation on [Event Log](/reference/events#event-log) and [APIs](/reference/api/unleash/get-events-for-toggle) to learn more. ## Flag Automation and Workflow Integration for Django Apps diff --git a/website/docs/feature-flag-tutorials/dotnet/dotnet-examples.md b/website/docs/feature-flag-tutorials/dotnet/dotnet-examples.md index 9f56075370..e6c86e0115 100644 --- a/website/docs/feature-flag-tutorials/dotnet/dotnet-examples.md +++ b/website/docs/feature-flag-tutorials/dotnet/dotnet-examples.md @@ -312,15 +312,15 @@ This is especially true in very regulated environments like health care, insuran Unleash provides the data to log any change over time at the flag level and at the project level. Logs are useful for downstream data warehouses or data lakes. -You can view Event logs to monitor the changes to flag strategies and statuses, like: +You can view [Event Log](/reference/events#event-log) to monitor the changes to flag strategies and statuses, like: - When the flag was created - How the gradual rollout strategy was configured - When and how the variants were created and configured -![Event logs in Unleash track every single change made to flags, similar to Git commit history.](../ruby/event-logs.png) +![Event Log in Unleash tracks every single change made to flags, similar to Git commit history.](../ruby/event-logs.png) -You can also retrieve event logs by using an API command, like below: +You can also retrieve events by using an API command, like below: ```csharp HttpClient client = new HttpClient(); @@ -336,7 +336,7 @@ var responseBody = await response.Content.ReadAsStringAsync(); Console.WriteLine(responseBody); ``` -Read our documentation on [Event logs](/reference/event-log) and [APIs](/reference/api/unleash/get-events-for-toggle) to learn more. +Read our documentation on [Event Log](/reference/events#event-log) and [APIs](/reference/api/unleash/get-events-for-toggle) to learn more. ## Flag Automation and Workflow Integration for .NET Apps diff --git a/website/docs/feature-flag-tutorials/ios/examples.md b/website/docs/feature-flag-tutorials/ios/examples.md index 9ff0bce569..4712b2c9c7 100644 --- a/website/docs/feature-flag-tutorials/ios/examples.md +++ b/website/docs/feature-flag-tutorials/ios/examples.md @@ -274,15 +274,15 @@ Because a feature flag service controls how an application behaves in production Unleash provides the data to log any change over time at the flag level and at the project level. Logs are useful for downstream data warehouses or data lakes. Tools like [Splunk](https://www.splunk.com/) can help you combine logs and run advanced queries against them. -For our iOS app, we can view Event logs to monitor the changes to flag strategies and statuses we have made throughout our examples, such as: +For our iOS app, we can view events in [Event Log](/reference/events#event-log) to monitor the changes to flag strategies and statuses we have made throughout our examples, such as: - When the flag was created - How the gradual rollout strategy was configured - When and how the variants were created and configured -![Feature flag event log. The flag's variant's have been updated.](/img/ios-ex-event-logs.png) +![Feature flag events showing that the flag's variants have been updated.](/img/ios-ex-event-logs.png) -You can also retrieve event log data by using an API command below: +You can also retrieve events by using the API command below: ``` curl -L -X GET '/api/admin/events/:featureName' \ @@ -290,7 +290,7 @@ curl -L -X GET '/api/admin/events/:featureName' \ -H 'Authorization: ' ``` -Read our documentation on [Event logs](/reference/event-log) and [APIs](/reference/api/unleash/events) to learn more. +Read our documentation on [Event Log](/reference/events#event-log) and [APIs](/reference/api/unleash/events) to learn more. ## Change Management & Feature Flag Approvals in iOS diff --git a/website/docs/feature-flag-tutorials/java/spring-boot-examples.md b/website/docs/feature-flag-tutorials/java/spring-boot-examples.md index 30c67cd854..1dbb603686 100644 --- a/website/docs/feature-flag-tutorials/java/spring-boot-examples.md +++ b/website/docs/feature-flag-tutorials/java/spring-boot-examples.md @@ -216,15 +216,15 @@ Because a feature flag service controls how an application behaves in production Unleash provides the data to log any change over time at the flag level and the project level. Logs are useful for downstream data warehouses or data lakes. Tools like Splunk can help you combine logs and run advanced queries against them. -For our Spring Boot app, we can view Event logs to monitor the changes to flag strategies and statuses we have made throughout our examples, such as: +For our Spring Boot app, we can view events in [Event Log](/reference/events#event-log) to monitor the changes to flag strategies and statuses we have made throughout our examples, such as: - When the flag was created - How the gradual rollout strategy was configured - When and how the variants were created and configured -![Event logs in Unleash track every single change made to flags, similar to Git commit history.](/img/spring-boot-events-log.png) +![Event Log in Unleash tracks every single change made to flags, similar to Git commit history.](/img/spring-boot-events-log.png) -You can also retrieve event log data by using an API command. Read our documentation on [Event logs](/reference/event-log) and [APIs](/reference/api/unleash/get-events-for-toggle) to learn more. +You can also retrieve events by using an API command. Read our documentation on [Event Log](/reference/events#event-log) and [APIs](/reference/api/unleash/get-events-for-toggle) to learn more. ## Flag Automation & Workflow Integration for Java Apps diff --git a/website/docs/feature-flag-tutorials/python/examples.md b/website/docs/feature-flag-tutorials/python/examples.md index 8fb3d32986..eb974ec4ad 100644 --- a/website/docs/feature-flag-tutorials/python/examples.md +++ b/website/docs/feature-flag-tutorials/python/examples.md @@ -347,15 +347,15 @@ Because a feature flag service controls how an application behaves in production Unleash provides the data to log any change over time at the flag level and at the project level. Logs are useful for downstream data warehouses or data lakes. Tools like [Splunk](https://www.splunk.com/) can help you combine logs and run advanced queries against them. -For our Python app, we can view Event logs to monitor the changes to flag strategies and statuses we have made throughout our examples, such as: +For our Python app, we can view events in [Event Log](/reference/events#event-log) to monitor the changes to flag strategies and statuses we have made throughout our examples, such as: - When the flag was created - How the gradual rollout strategy was configured - When and how the variants were created and configured -![Event logs in Unleash track every single change made to flags, similar to Git commit history.](/img/python-ex-logs.png) +![Event Log in Unleash tracks every single change made to flags, similar to Git commit history.](/img/python-ex-logs.png) -You can also retrieve event log data by using an API command below: +You can also retrieve events by using the API command below: ```py import requests @@ -373,7 +373,7 @@ response = requests.request("GET", url, headers=headers, data=payload) print(response.text) ``` -Read our documentation on [Event logs](/reference/event-log) and [APIs](/reference/api/unleash/get-events-for-toggle) to learn more. +Read our documentation on [Event Log](/reference/events#event-log) and [APIs](/reference/api/unleash/get-events-for-toggle) to learn more. ## Flag Automation & Workflow Integration for Python Apps diff --git a/website/docs/feature-flag-tutorials/rails/rails-examples.md b/website/docs/feature-flag-tutorials/rails/rails-examples.md index 8e4584d099..fa6808c214 100644 --- a/website/docs/feature-flag-tutorials/rails/rails-examples.md +++ b/website/docs/feature-flag-tutorials/rails/rails-examples.md @@ -309,15 +309,15 @@ This is especially true in very regulated environments like health care, insuran Unleash provides the data to log any change over time at the flag level and at the project level. Logs are useful for downstream data warehouses or data lakes. -You can view Event logs to monitor the changes to flag strategies and statuses, like: +You can view events in [Event Log](/reference/events#event-log) to monitor the changes to flag strategies and statuses, like: - When the flag was created - How the gradual rollout strategy was configured - When and how the variants were created and configured -![Event logs in Unleash track every single change made to flags, similar to Git commit history.](../ruby/event-logs.png) +![Event Log in Unleash tracks every single change made to flags, similar to Git commit history.](../ruby/event-logs.png) -You can also retrieve event logs by using an API command, like below: +You can also retrieve events by using an API command, like below: ```ruby require 'httpx' @@ -333,7 +333,7 @@ response = HTTPX.get(url, headers: headers) puts response.body ``` -Read our documentation on [Event logs](/reference/event-log) and [APIs](/reference/api/unleash/get-events-for-toggle) to learn more. +Read our documentation on [Event Log](/reference/events#event-log) and [APIs](/reference/api/unleash/get-events-for-toggle) to learn more. ## Flag Automation and Workflow Integration for Rails Apps diff --git a/website/docs/feature-flag-tutorials/react/examples.md b/website/docs/feature-flag-tutorials/react/examples.md index 4798007683..4148f44bd6 100644 --- a/website/docs/feature-flag-tutorials/react/examples.md +++ b/website/docs/feature-flag-tutorials/react/examples.md @@ -400,15 +400,15 @@ Fortunately, this is straightforward in Unleash Enterprise. Unleash provides the data to log any change that has happened over time, at the flag level from a global level. In conjunction with Unleash, tools like [Splunk](https://www.splunk.com/) can help you combine logs and run advanced queries against them. Logs are useful for downstream data warehouses or data lakes. -In our React tutorial application, we can view Event logs to monitor the changes to flag strategies and statuses we have made throughout our examples, such as: +For our React tutorial application, we can view events in [Event Log](/reference/events#event-log) to monitor the changes to flag strategies and statuses we have made throughout our examples, such as: - When the `newNotificationsBadge` flag was created - How the gradual rollout strategy was configured - When and how the variants were created and configured -![Feature flag event log. The flag's variant's have been updated.](/img/react-ex-event-log.png) +![Feature flag events showing that the flag's variants have been updated.](/img/react-ex-event-log.png) -You can also retrieve event log data by using an API command below: +You can also retrieve events by using the API command below: ``` curl -L -X GET '/api/admin/events/:featureName' \ @@ -416,7 +416,7 @@ curl -L -X GET '/api/admin/events/:featureName' \ -H 'Authorization: ' ``` -Read our documentation on [Event logs](/reference/event-log) and [APIs](/reference/api/unleash/events) to learn more. +Read our documentation on [Event Log](/reference/events#event-log) and [APIs](/reference/api/unleash/events) to learn more. ## Change Management & Feature Flag Approvals in React diff --git a/website/docs/feature-flag-tutorials/ruby/ruby-examples.md b/website/docs/feature-flag-tutorials/ruby/ruby-examples.md index 4bd82ac02c..3ba6fa36d6 100644 --- a/website/docs/feature-flag-tutorials/ruby/ruby-examples.md +++ b/website/docs/feature-flag-tutorials/ruby/ruby-examples.md @@ -308,15 +308,15 @@ This is especially true in very regulated environments like health care, insuran Unleash provides the data to log any change over time at the flag level and at the project level. Logs are useful for downstream data warehouses or data lakes. -You can view Event logs to monitor the changes to flag strategies and statuses, like: +You can view [Event Log](/reference/events#event-log) to monitor the changes to flag strategies and statuses, like: - When the flag was created - How the gradual rollout strategy was configured - When and how the variants were created and configured -![Event logs in Unleash track every single change made to flags, similar to Git commit history.](./event-logs.png) +![Event Log in Unleash tracks every single change made to flags, similar to Git commit history.](./event-logs.png) -You can also retrieve event logs by using an API command, like below: +You can also retrieve events by using an API command, like below: ```ruby require 'httpx' @@ -332,7 +332,7 @@ response = HTTPX.get(url, headers: headers) puts response.body ``` -Read our documentation on [Event logs](/reference/event-log) and [APIs](/reference/api/unleash/get-events-for-toggle) to learn more. +Read our documentation on [Event Log](/reference/events#event-log) and [APIs](/reference/api/unleash/get-events-for-toggle) to learn more. ## Flag Automation & Workflow Integration for Ruby Apps diff --git a/website/docs/feature-flag-tutorials/rust/rust-examples.md b/website/docs/feature-flag-tutorials/rust/rust-examples.md index 70c01fc713..c956c9e322 100644 --- a/website/docs/feature-flag-tutorials/rust/rust-examples.md +++ b/website/docs/feature-flag-tutorials/rust/rust-examples.md @@ -372,15 +372,15 @@ This is especially true in very regulated environments like health care, insuran Unleash provides the data to log any change over time at the flag level and at the project level. Logs are useful for downstream data warehouses or data lakes. -You can view Event logs to monitor the changes to flag strategies and statuses, like: +You can view events in [Event Log](/reference/events#event-log) to monitor the changes to flag strategies and statuses, like: - When the flag was created - How the gradual rollout strategy was configured - When and how the variants were created and configured -![Event logs in Unleash track every single change made to flags, similar to Git commit history.](../ruby/event-logs.png) +![Event Log in Unleash tracks every single change made to flags, similar to Git commit history.](../ruby/event-logs.png) -You can also retrieve event logs by using an API command, like below: +You can also retrieve events by using an API command, like below: ```rust use reqwest::blocking::Client; @@ -406,7 +406,7 @@ fn main() -> Result<(), Box> { } ``` -Read our documentation on [Event logs](/reference/event-log) and [APIs](/reference/api/unleash/get-events-for-toggle) to learn more. +Read our documentation on [Event Log](/reference/events#event-log) and [APIs](/reference/api/unleash/get-events-for-toggle) to learn more. ## Flag Automation and Workflow Integration for Rust Apps diff --git a/website/docs/feature-flag-tutorials/use-cases/gradual-rollout.md b/website/docs/feature-flag-tutorials/use-cases/gradual-rollout.md index 9181265b96..68dea0d7da 100644 --- a/website/docs/feature-flag-tutorials/use-cases/gradual-rollout.md +++ b/website/docs/feature-flag-tutorials/use-cases/gradual-rollout.md @@ -164,9 +164,9 @@ Fortunately, this is straightforward in Unleash Enterprise. Unleash provides the data to log any change that has happened over time, at the flag level from a global level. In conjunction with Unleash, tools like Splunk can help you combine logs and run advanced queries against them. Logs are useful for downstream data warehouses or data lakes. -![The event log for a feature flag. The "Event log" tab is highlighted and the UI shows the most recent changes, including a JSON diff and the change details.](/img/unleash-toggle-history.png) +![Events for a feature flag. The Event log tab is highlighted and the UI shows the most recent changes, including a JSON diff and the change details.](/img/unleash-toggle-history.png) -Learn more about [event logs](/reference/event-log/) in our documentation. +Learn more about [Event Log](/reference/events#event-log/) in our documentation. ### Managing Change Requests diff --git a/website/docs/how-to/how-to-use-the-admin-api.md b/website/docs/how-to/how-to-use-the-admin-api.md index 41da452914..65eecc7ce2 100644 --- a/website/docs/how-to/how-to-use-the-admin-api.md +++ b/website/docs/how-to/how-to-use-the-admin-api.md @@ -28,9 +28,9 @@ curl -X POST -H "Content-Type: application/json" \ https://app.unleash-hosted.com/demo/api/admin/features/Demo/toggle/on ``` -**Great success!** We have now enabled the feature flag. We can also verify that it was actually changed by the API user by navigating to the Event log (history) for this feature flag. +**Great success!** We have now enabled the feature flag. We can also verify that it was actually changed by the API user by navigating to [Event Log](/reference/events#event-log) and filtering events for this feature flag. -![A feature flag's event log showing that it was last updated by "admin-api".](/img/api_access_history.png) +![Feature flag events showing that it was last updated by "admin-api".](/img/api_access_history.png) ## API overview {#api-overview} diff --git a/website/docs/reference/actions.md b/website/docs/reference/actions.md index 0c23c1ddda..eecc139624 100644 --- a/website/docs/reference/actions.md +++ b/website/docs/reference/actions.md @@ -46,7 +46,7 @@ Filters are completely optional, so if you don't configure any filter your actio ### Actions -When these actions are triggered, they will execute under the identity of a [service account](./service-accounts.md). This means that when you later check the [event log](./event-log) you will see this service account as the actor for those events. In order to execute the configured actions successfully, this service account needs to have the necessary permissions. This service account doesn't need an API token, so when creating it you can skip the token generation step and simply make sure it has the necessary permissions. +When these actions are triggered, they execute using the identity of a [service account](./service-accounts.md). As a result, when you later view events in [Event Log](./events#event-log), you’ll see this service account listed as the actor for those events. In order to execute the configured actions successfully, this service account needs to have the necessary permissions. This service account doesn't need an API token, so when creating it you can skip the token generation step and simply make sure it has the necessary permissions. The actions are executed in the same order that they are defined. If a previous action fails, the following actions will not be started. You can add multiple actions to an action set and you can add multiple action sets to a project. Depending on the action you want to execute you will have to provide different parameters. diff --git a/website/docs/reference/api-tokens-and-client-keys.mdx b/website/docs/reference/api-tokens-and-client-keys.mdx index 80d634e390..e32413dcb3 100644 --- a/website/docs/reference/api-tokens-and-client-keys.mdx +++ b/website/docs/reference/api-tokens-and-client-keys.mdx @@ -82,7 +82,7 @@ We do not recommend using admin tokens anymore, they are not connected to any us **Personal access tokens** are a special form of admin tokens and grant access to the same resources that the user that created them has access to. These permissions are dynamic, so if a user's permissions change through addition of a custom role, the token will likewise have altered permissions. -When using a personal access token to modify resources, the event log will list the token creator's name for that operation. +When you use a personal access token to modify resources, the events record the token creator's name for that operation. Personal access tokens with a lifetime **will stop working after the expiration date**. diff --git a/website/docs/reference/api/legacy/unleash/admin/events.md b/website/docs/reference/api/legacy/unleash/admin/events.md index f84566c565..34fa81a155 100644 --- a/website/docs/reference/api/legacy/unleash/admin/events.md +++ b/website/docs/reference/api/legacy/unleash/admin/events.md @@ -10,7 +10,7 @@ In order to access the admin API endpoints you need to identify yourself. Unless ::: -The Events API lets you retrieve [events](/reference/event-types.mdx) from your Unleash instance. +The Events API lets you retrieve [events](/reference/events.mdx) from your Unleash instance. ## Event endpoints @@ -131,6 +131,6 @@ The list of events related to the given toggle. :::note Content moved -This section has been moved to a dedicated [event type reference document](/reference/event-types.mdx). +This section has been moved to a dedicated [events documentation](/reference/events.mdx). ::: diff --git a/website/docs/reference/event-log.md b/website/docs/reference/event-log.md deleted file mode 100644 index 04626030c6..0000000000 --- a/website/docs/reference/event-log.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -title: Event Log ---- - -The event log lets you track changes in Unleash. It lists _what_ changed, _when_ it changed, and _who_ performed the change. - -## Feature flag log {#event-log-per-feature-toggle} - - - -Each feature flag has its own event log. The event log is available under the "Event log" tab in the tab view. - -![The event log for a feature flag. The "Event log" tab is highlighted and the UI shows the most recent changes, including a JSON diff and the change details.](/img/unleash-toggle-history.png) - -## Global Event Log {#global-event-log} - - - -Unleash also keeps an event log across all flags and activation strategies, tracking all changes. You access the global event log via the “event log”, which you can find in the drawer menu. The global event log is only accessible by users with instance admin access. - -![The global event log and how to get there. It shows a number of events and their changes as well as the navigation steps: use the admin menu and navigate to "event history".](/img/global_audit_log.png) diff --git a/website/docs/reference/event-types.mdx b/website/docs/reference/event-types.mdx deleted file mode 100644 index 4464ee62aa..0000000000 --- a/website/docs/reference/event-types.mdx +++ /dev/null @@ -1,1472 +0,0 @@ ---- -title: Event Types ---- - -Unleash emits a large number of different events (described in more detail in the next sections). The exact fields an event contains varies from event to event, but they all conform to the following TypeScript interface before being transformed to JSON: - -```ts -interface IEvent { - id: number; - createdAt: Date; - type: string; - createdBy: string; - project?: string; - environment?: string; - featureName?: string; - data?: any; - preData?: any; - tags?: ITag[]; -} -``` - -The event properties are described in short in the table below. For more info regarding specific event types, refer to the following sections. - -| Property | Description | -| --- | --- | -| `createdAt` | The time the event happened as a RFC 3339-conformant timestamp. | -| `data` | Extra associated data related to the event, such as feature flag state, segment configuration, etc., if applicable. | -| `environment` | The feature flag environment the event relates to, if applicable. | -| `featureName` | The name of the feature flag the event relates to, if applicable. | -| `id` | The ID of the event. An increasing natural number. | -| `preData` | Data relating to the previous state of the event's subject. | -| `project` | The project the event relates to, if applicable. | -| `tags` | Any tags related to the event, if applicable. | -| `type` | The event type, as described in the rest of this section. | - -## Feature flag events - -These events pertain to feature flags and their life cycle. - -### `feature-created` - -This event fires when you create a feature. The `data` property contains the details for the new feature. - -```json title="example event: feature-created" -{ - "id": 899, - "type": "feature-created", - "createdBy": "user@company.com", - "createdAt": "2022-05-31T13:32:20.560Z", - "data": { - "name": "new-feature", - "description": "Flag description", - "type": "release", - "project": "my-project", - "stale": false, - "variants": [], - "createdAt": "2022-05-31T13:32:20.547Z", - "lastSeenAt": null, - "impressionData": true - }, - "preData": null, - "tags": [], - "featureName": "new-feature", - "project": "my-project", - "environment": null -} -``` - -### `feature-updated` - -:::caution Deprecation notice - -This event type was replaced by more granular event types in Unleash 4.3. From Unleash 4.3 onwards, you'll need to use the events listed later in this section instead. - -::: - -This event fires when a feature gets updated in some way. The `data` property contains the new state of the flag. This is a legacy event, so it does not populate `preData` property. - -```json title="example event: feature-updated" -{ - "id": 899, - "type": "feature-updated", - "createdBy": "user@company.com", - "createdAt": "2022-05-31T13:32:20.560Z", - "data": { - "name": "new-feature", - "description": "Flag description", - "type": "release", - "project": "my-project", - "stale": false, - "variants": [], - "createdAt": "2022-05-31T13:32:20.547Z", - "lastSeenAt": null, - "impressionData": true - }, - "preData": null, - "tags": [], - "featureName": "new-feature", - "project": "my-project", - "environment": null -} -``` - -### `feature-deleted` - -This event fires when you delete a feature flag. The `preData` property contains the deleted flag data. - -```json title="example event: feature-deleted" -{ - "id": 903, - "type": "feature-deleted", - "createdBy": "admin-account", - "createdAt": "2022-05-31T14:06:14.574Z", - "data": null, - "preData": { - "name": "new-feature", - "type": "experiment", - "stale": false, - "project": "my-project", - "variants": [], - "createdAt": "2022-05-31T13:32:20.547Z", - "lastSeenAt": null, - "description": "Flag description", - "impressionData": true - }, - "tags": [], - "featureName": "new-feature", - "project": "my-project", - "environment": null -} -``` - -### `feature-archived` - -This event fires when you archive a flag. - -```json title="example event: feature-archived" -{ - "id": 902, - "type": "feature-archived", - "createdBy": "user@company.com", - "createdAt": "2022-05-31T14:04:38.661Z", - "data": null, - "preData": null, - "tags": [], - "featureName": "new-feature", - "project": "my-project", - "environment": null -} -``` - -### `feature-revived` - -This event fires when you revive an archived feature flag (when you take a flag out from the archive). - -```json title="example-event: feature-revived" -{ - "id": 914, - "type": "feature-revived", - "createdBy": "user@company.com", - "createdAt": "2022-06-01T09:57:10.719Z", - "data": null, - "preData": null, - "tags": [], - "featureName": "new-feature", - "project": "my-other-project", - "environment": null -} -``` - -### `feature-metadata-updated` - -This event fires when a feature's metadata (its description, flag type, or impression data settings) are changed. The `data` property contains the new flag data. The `preData` property contains the flag's previous data. - -The below example changes the flag's type from _release_ to _experiment_. - -```json title="example event: feature-metadata-updated" -{ - "id": 901, - "type": "feature-metadata-updated", - "createdBy": "user@company.com", - "createdAt": "2022-05-31T13:35:25.244Z", - "data": { - "name": "new-feature", - "description": "Flag description", - "type": "experiment", - "project": "my-project", - "stale": false, - "variants": [], - "createdAt": "2022-05-31T13:32:20.547Z", - "lastSeenAt": null, - "impressionData": true - }, - "preData": { - "name": "new-feature", - "type": "release", - "stale": false, - "project": "my-project", - "variants": [], - "createdAt": "2022-05-31T13:32:20.547Z", - "lastSeenAt": null, - "description": "Flag description", - "impressionData": true - }, - "tags": [], - "featureName": "new-feature", - "project": "my-project", - "environment": null -} -``` - -### `feature-project-change` - -This event fires when you move a feature from one project to another. The `data` property contains the names of the old and the new project. - -```json title="example event: feature-project-change" -{ - "id": 11, - "type": "feature-project-change", - "createdBy": "admin", - "createdAt": "2022-06-03T11:09:41.444Z", - "data": { - "newProject": "default", - "oldProject": "2" - }, - "preData": null, - "tags": [], - "featureName": "feature", - "project": "default", - "environment": null -} -``` - -### `feature-import` - -This event fires when you import a feature as part of an import process. The `data` property contains the feature data. - -```json title="example event: feature-import" -{ - "id": 26, - "type": "feature-import", - "createdBy": "import-API-token", - "createdAt": "2022-06-03T11:30:40.570Z", - "data": { - "name": "feature", - "description": "", - "type": "release", - "project": "default", - "stale": false, - "variants": [], - "impressionData": false, - "enabled": false, - "archived": false - }, - "preData": null, - "tags": [], - "featureName": null, - "project": null, - "environment": null -} -``` - -### `feature-tagged` - -This event fires when you add a tag to a feature. The `data` property contains the new tag. - -```json title="example event: feature-tagged" -{ - "id": 897, - "type": "feature-tagged", - "createdBy": "user@company.com", - "createdAt": "2022-05-31T13:06:31.047Z", - "data": { - "type": "simple", - "value": "tag2" - }, - "preData": null, - "tags": [], - "featureName": "example-feature-name", - "project": null, - "environment": null -} -``` - -### `feature-untagged` - -This event fires when you remove a tag from a flag. The `data` property contains the tag that was removed. - -```json title="example event: feature-untagged" -{ - "id": 893, - "type": "feature-untagged", - "createdBy": "user@company.com", - "createdAt": "2022-05-31T12:58:10.241Z", - "data": { - "type": "simple", - "value": "thisisatag" - }, - "preData": null, - "tags": [], - "featureName": "example-feature-name", - "project": null, - "environment": null -} -``` - -### `feature-tag-import` - -This event fires when you import a tagged feature as part of an import job. The `data` property contains the name of the feature and the tag. - -```json title="example event: feature-tag-import" -{ - "id": 43, - "type": "feature-tag-import", - "createdBy": "import-API-token", - "createdAt": "2022-06-03T11:30:40.606Z", - "data": { - "featureName": "new-feature", - "tag": { - "type": "simple", - "value": "tag1" - } - }, - "preData": null, - "tags": [], - "featureName": null, - "project": null, - "environment": null -} -``` - -### `feature-strategy-add` - -This event fires when you add a strategy to a feature. The `data` property contains the configuration for the new strategy. - -```json title="example event: feature-strategy-add" -{ - "id": 919, - "type": "feature-strategy-add", - "createdBy": "user@company.com", - "createdAt": "2022-06-01T10:03:08.290Z", - "data": { - "id": "3f4bf713-696c-43a4-8ce7-d6c607108858", - "name": "flexibleRollout", - "constraints": [], - "parameters": { - "groupId": "new-feature", - "rollout": "67", - "stickiness": "default" - } - }, - "preData": null, - "tags": [], - "featureName": "new-feature", - "project": "my-other-project", - "environment": "default" -} -``` - -### `feature-strategy-update` - -This event fires when you update a feature strategy. The `data` property contains the new strategy configuration. The `preData` property contains the previous strategy configuration. - -```json title="example event: feature-strategy-update" -{ - "id": 920, - "type": "feature-strategy-update", - "createdBy": "user@company.com", - "createdAt": "2022-06-01T10:03:11.549Z", - "data": { - "id": "3f4bf713-696c-43a4-8ce7-d6c607108858", - "name": "flexibleRollout", - "constraints": [], - "parameters": { - "groupId": "new-feature", - "rollout": "32", - "stickiness": "default" - } - }, - "preData": { - "id": "3f4bf713-696c-43a4-8ce7-d6c607108858", - "name": "flexibleRollout", - "parameters": { - "groupId": "new-feature", - "rollout": "67", - "stickiness": "default" - }, - "constraints": [] - }, - "tags": [], - "featureName": "new-feature", - "project": "my-other-project", - "environment": "default" -} -``` - -### `feature-strategy-remove` - -This event fires when you remove a strategy from a feature. The `preData` contains the configuration of the strategy that was removed. - -```json title="example event: feature-strategy-remove" -{ - "id": 918, - "type": "feature-strategy-remove", - "createdBy": "user@company.com", - "createdAt": "2022-06-01T10:03:00.229Z", - "data": null, - "preData": { - "id": "9591090e-acb0-4088-8958-21faaeb7147d", - "name": "default", - "parameters": {}, - "constraints": [] - }, - "tags": [], - "featureName": "new-feature", - "project": "my-other-project", - "environment": "default" -} -``` - -### `feature-stale-on` - -This event fires when you mark a feature as stale. - -```json title="example event: feature-stale-on" -{ - "id": 926, - "type": "feature-stale-on", - "createdBy": "user@company.com", - "createdAt": "2022-06-01T10:10:46.737Z", - "data": null, - "preData": null, - "tags": [ - { - "value": "tag", - "type": "simple" - }, - { - "value": "tog", - "type": "simple" - } - ], - "featureName": "new-feature", - "project": "my-other-project", - "environment": null -} -``` - -### `feature-stale-off` - -This event fires when you mark a stale feature as no longer being stale. - -```json title="example event: feature-stale-off" -{ - "id": 928, - "type": "feature-stale-off", - "createdBy": "user@company.com", - "createdAt": "2022-06-01T10:10:52.790Z", - "data": null, - "preData": null, - "tags": [ - { - "value": "tag", - "type": "simple" - }, - { - "value": "tog", - "type": "simple" - } - ], - "featureName": "new-feature", - "project": "my-other-project", - "environment": null -} -``` - -### `feature-environment-enabled` - -This event fires when you enable an environment for a feature. The `environment` property contains the name of the environment. - -```json title="example event: feature-environment-enabled" -{ - "id": 930, - "type": "feature-environment-enabled", - "createdBy": "user@company.com", - "createdAt": "2022-06-02T12:09:03.045Z", - "data": null, - "preData": null, - "tags": [ - { - "value": "tag", - "type": "simple" - }, - { - "value": "tog", - "type": "simple" - } - ], - "featureName": "new-feature", - "project": "my-other-project", - "environment": "development" -} -``` - -### `feature-environment-disabled` - -This event fires when you disable an environment for a feature. The `environment` property contains the name of the environment. - -```json title="example event: feature-environment-disabled" -{ - "id": 931, - "type": "feature-environment-disabled", - "createdBy": "user@company.com", - "createdAt": "2022-06-02T12:09:04.469Z", - "data": null, - "preData": null, - "tags": [ - { - "value": "tag", - "type": "simple" - }, - { - "value": "tog", - "type": "simple" - } - ], - "featureName": "new-feature", - "project": "my-other-project", - "environment": "development" -} -``` - -### `drop-features` - -This event fires when you delete existing features as part of an import job. The `data.name` property will always be `"all-features"`. - -```json title="example event: drop-features" -{ - "id": 25, - "type": "drop-features", - "createdBy": "import-API-token", - "createdAt": "2022-06-03T11:30:40.563Z", - "data": { - "name": "all-features" - }, - "preData": null, - "tags": [], - "featureName": null, - "project": null, - "environment": null -} -``` - -### `drop-feature-tags` - -This event fires when you drop all existing tags as part of a configuration import. The `data.name` property will always be `"all-feature-tags"`. - -```json title="example event: drop-feature-tags" -{ - "id": 36, - "type": "drop-feature-tags", - "createdBy": "import-API-token", - "createdAt": "2022-06-03T11:30:40.596Z", - "data": { - "name": "all-feature-tags" - }, - "preData": null, - "tags": [], - "featureName": null, - "project": null, - "environment": null -} -``` - -### `feature-potentially-stale-on` - -This event fires when Unleash marks a feature flag as potentially stale. Feature flags are marked as potentially stale when they exceed the expected lifetime of their [feature flag type](/reference/feature-toggle-types.md). - -``` json title="Example event when my-feature is marked as potentially stale" -{ - "id": 561, - "type": "feature-potentially-stale-on", - "createdBy": "unleash-system", - "createdAt": "2023-07-19T09:12:31.313Z", - "data": null, - "preData": null, - "tags": [], - "featureName": "helix", - "project": "viridian-forest", - "environment": null -} -``` - -## Strategy events - -### `strategy-created` - -This event fires when you create a strategy. The `data` property contains the strategy configuration. - -```json title="example event: strategy-created" -{ - "id": 932, - "type": "strategy-created", - "createdBy": "user@company.com", - "createdAt": "2022-06-02T12:20:52.111Z", - "data": { - "name": "new-strategy", - "description": "this strategy does ...", - "parameters": [], - "editable": true, - "deprecated": false - }, - "preData": null, - "tags": [], - "featureName": null, - "project": null, - "environment": null -} -``` - -### `strategy-updated` - -This event fires when you change a strategy's configuration. The `data` property contains the new strategy configuration. - -```json title="example event: strategy-updated" -{ - "id": 933, - "type": "strategy-updated", - "createdBy": "user@company.com", - "createdAt": "2022-06-02T12:21:23.741Z", - "data": { - "name": "new-strategy", - "description": "this strategy does something else!", - "parameters": [], - "editable": true, - "deprecated": false - }, - "preData": null, - "tags": [], - "featureName": null, - "project": null, - "environment": null -} -``` - -### `strategy-deleted` - -This event fires when you delete a strategy. The `data` property contains the name of the deleted strategy. - -```json title="example event: strategy-deleted" -{ - "id": 936, - "type": "strategy-deleted", - "createdBy": "user@company.com", - "createdAt": "2022-06-02T12:22:01.302Z", - "data": { - "name": "new-strategy" - }, - "preData": null, - "tags": [], - "featureName": null, - "project": null, - "environment": null -} -``` - -### `strategy-deprecated` - -This event fires when you deprecate a strategy. The `data` property contains the name of the deprecated strategy. - -```json title="example event: strategy-deprecated" -{ - "id": 934, - "type": "strategy-deprecated", - "createdBy": "user@company.com", - "createdAt": "2022-06-02T12:21:45.041Z", - "data": { - "name": "new-strategy" - }, - "preData": null, - "tags": [], - "featureName": null, - "project": null, - "environment": null -} -``` - -### `strategy-reactivated` - -This event fires when you bring reactivate a deprecated strategy. The `data` property contains the name of the reactivated strategy. - -```json title="example event: strategy-reactivated" -{ - "id": 935, - "type": "strategy-reactivated", - "createdBy": "user@company.com", - "createdAt": "2022-06-02T12:21:49.010Z", - "data": { - "name": "new-strategy" - }, - "preData": null, - "tags": [], - "featureName": null, - "project": null, - "environment": null -} -``` - -### `strategy-import` - -This event fires when you import a strategy as part of an import job. The `data` property contains the strategy's configuration. - -```json title="example event: strategy-import" -{ - "id": 29, - "type": "strategy-import", - "createdBy": "import-API-token", - "createdAt": "2022-06-03T11:30:40.583Z", - "data": { - "name": "gradualRolloutSessionId", - "description": "Gradually activate feature flag. Stickiness based on session id.", - "parameters": [ - { - "name": "percentage", - "type": "percentage", - "description": "", - "required": false - }, - { - "name": "groupId", - "type": "string", - "description": "Used to define a activation groups, which allows you to correlate across feature flags.", - "required": true - } - ], - "deprecated": true - }, - "preData": null, - "tags": [], - "featureName": null, - "project": null, - "environment": null -} -``` - -### `drop-strategies` - -This event fires when you delete existing strategies as part of an important job. The `data.name` property will always be `"all-strategies"`. - -```json title="example event: drop-strategies" -{ - "id": 28, - "type": "drop-strategies", - "createdBy": "import-API-token", - "createdAt": "2022-06-03T11:30:40.579Z", - "data": { - "name": "all-strategies" - }, - "preData": null, - "tags": [], - "featureName": null, - "project": null, - "environment": null -} -``` - -## Context field events - -### `context-field-created` - -This event fires when you create a context field. The `data` property contains the context field configuration. - -```json title="example event: context-field-created" -{ - "id": 937, - "type": "context-field-created", - "createdBy": "user@company.com", - "createdAt": "2022-06-02T13:17:17.499Z", - "data": { - "name": "new-context-field", - "description": "this context field is for describing events", - "legalValues": [], - "stickiness": false - }, - "preData": null, - "tags": [], - "featureName": null, - "project": null, - "environment": null -} -``` - -### `context-field-updated` - -This event fires when you update a context field. The `data` property contains the new context field configuration. - -```json title="example event: context-field-updated" -{ - "id": 939, - "type": "context-field-updated", - "createdBy": "user@company.com", - "createdAt": "2022-06-02T13:19:19.422Z", - "data": { - "name": "new-context-field", - "description": "this context field is for describing events", - "legalValues": [ - { - "value": "0fcf7d07-276c-41e1-a207-e62876d9c949", - "description": "Red team" - }, - { - "value": "176ab647-4d50-41bf-afe0-f8b856d9bbb9", - "description": "Blue team" - } - ], - "stickiness": false - }, - "preData": null, - "tags": [], - "featureName": null, - "project": null, - "environment": null -} -``` - -### `context-field-deleted` - -This event fires when you delete a context field. The `data` property contains the name of the deleted context field. - -```json title="example event: context-field-deleted" -{ - "id": 940, - "type": "context-field-deleted", - "createdBy": "user@company.com", - "createdAt": "2022-06-02T13:20:41.386Z", - "data": { - "name": "new-context-field" - }, - "preData": null, - "tags": [], - "featureName": null, - "project": null, - "environment": null -} -``` - -## Project events - -### `project-created` - -This event fires when you create a project. The `data` property contains the project configuration. - -```json title="example event: project-created" -{ - "id": 905, - "type": "project-created", - "createdBy": "user@company.com", - "createdAt": "2022-05-31T14:16:14.498Z", - "data": { - "id": "my-other-project", - "name": "my other project", - "description": "a project for important work" - }, - "preData": null, - "tags": [], - "featureName": null, - "project": "my-other-project", - "environment": null -} -``` - -### `project-updated` - -This event fires when you update a project's configuration. The `data` property contains the new project configuration. The `preData` property contains the previous project configuration. - -```json title="example event: project-updated" -{ - "id": 941, - "type": "project-updated", - "createdBy": "user@company.com", - "createdAt": "2022-06-02T13:23:55.025Z", - "data": { - "id": "my-other-project", - "name": "my other project", - "description": "a project for important work!" - }, - "preData": { - "id": "my-other-project", - "name": "my other project", - "health": 50, - "createdAt": "2022-05-31T14:16:14.483Z", - "updatedAt": "2022-06-02T12:30:48.095Z", - "description": "a project for important work" - }, - "tags": [], - "featureName": null, - "project": "my-other-project", - "environment": null -} -``` - -### `project-deleted` - -This event fires when you delete a project. The `project` property contains the name of the deleted project. - -```json title="example event: project-deleted" -{ - "id": 944, - "type": "project-deleted", - "createdBy": "user@company.com", - "createdAt": "2022-06-02T13:25:53.820Z", - "data": null, - "preData": null, - "tags": [], - "featureName": null, - "project": "my-other-project", - "environment": null -} -``` - -### `project-import` - -This event fires when you import a project. The `data` property contains the project's configuration details. - -```json title="example event: project-import" -{ - "id": 35, - "type": "project-import", - "createdBy": "import-API-token", - "createdAt": "2022-06-03T11:30:40.591Z", - "data": { - "id": "default", - "name": "Default", - "description": "Default project", - "createdAt": "2022-06-03T09:30:40.587Z", - "health": 100, - "updatedAt": "2022-06-03T11:30:40.587Z" - }, - "preData": null, - "tags": [], - "featureName": null, - "project": null, - "environment": null -} -``` - -### `drop-projects` - -This event fires when you delete existing projects as part of an import job. The `data.name` property will always be `"all-projects"`. - -```json title="example event: drop-projects" -{ - "id": 33, - "type": "drop-projects", - "createdBy": "import-API-token", - "createdAt": "2022-06-03T11:30:40.586Z", - "data": { - "name": "all-projects" - }, - "preData": null, - "tags": [], - "featureName": null, - "project": null, - "environment": null -} -``` - -## Tag events - -### `tag-created` - -This event fires when you create a new tag. The `data` property contains the tag that was created. - -```json title="example event: tag-created" -{ - "id": 959, - "type": "feature-tagged", - "createdBy": "user@company.com", - "createdAt": "2022-06-03T10:13:39.401Z", - "data": { - "type": "heartag", - "value": "tag-value" - }, - "preData": null, - "tags": [], - "featureName": "new-feature", - "project": null, - "environment": null -} -``` - -### `tag-deleted` - -This event fires when you delete a tag. The `data` property contains the tag that was deleted. - -```json title="example event: tag-deleted" -{ - "id": 957, - "type": "tag-deleted", - "createdBy": "user@company.com", - "createdAt": "2022-06-03T10:12:17.310Z", - "data": { - "type": "heartag", - "value": "tag-value" - }, - "preData": null, - "tags": [], - "featureName": null, - "project": null, - "environment": null -} -``` - -### `tag-import` - -This event fires when you import a tag as part of an import job. The `data` property contains the imported tag. - -```json title="example event: tag-import" -{ - "id": 41, - "type": "tag-import", - "createdBy": "import-API-token", - "createdAt": "2022-06-03T11:30:40.603Z", - "data": { - "type": "simple", - "value": "tag1" - }, - "preData": null, - "tags": [], - "featureName": null, - "project": null, - "environment": null -} -``` - -### `drop-tags` - -This event fires when you delete existing tags as part of an import job. The `data.name` property will always be `"all-tags"`. - -```json title="example event: drop-tags" -{ - "id": 37, - "type": "drop-tags", - "createdBy": "import-API-token", - "createdAt": "2022-06-03T11:30:40.596Z", - "data": { - "name": "all-tags" - }, - "preData": null, - "tags": [], - "featureName": null, - "project": null, - "environment": null -} -``` - -## Tag type events - -### `tag-type-created` - -This event fires when you create a new tag type. The `data` property contains the tag type configuration. - -```json title="example event: tag-type-created" -{ - "id": 945, - "type": "tag-type-created", - "createdBy": "user@company.com", - "createdAt": "2022-06-02T13:27:01.235Z", - "data": { - "name": "new-tag-type", - "description": "event testing" - }, - "preData": null, - "tags": [], - "featureName": null, - "project": null, - "environment": null -} -``` - -### `tag-type-updated` - -This event fires when you update a tag type. The `data` property contains the new tag type configuration. - -```json title="example event: tag-type-updated" -{ - "id": 946, - "type": "tag-type-updated", - "createdBy": "user@company.com", - "createdAt": "2022-06-02T13:27:31.126Z", - "data": { - "name": "new-tag-type", - "description": "This tag is for testing events." - }, - "preData": null, - "tags": [], - "featureName": null, - "project": null, - "environment": null -} -``` - -### `tag-type-deleted` - -This event fires when you delete a tag type. The `data` property contains the name of the deleted tag type. - -```json title="example event: tag-type-deleted" -{ - "id": 947, - "type": "tag-type-deleted", - "createdBy": "user@company.com", - "createdAt": "2022-06-02T13:27:37.277Z", - "data": { - "name": "new-tag-type" - }, - "preData": null, - "tags": [], - "featureName": null, - "project": null, - "environment": null -} -``` - -### `tag-type-import` - -This event fires when you import a tag type as part of an import job. The `data` property contains the imported tag. - -```json title="example event: tag-type-import" -{ - "id": 40, - "type": "tag-type-import", - "createdBy": "import-API-token", - "createdAt": "2022-06-03T11:30:40.599Z", - "data": { - "name": "custom-tag-type", - "description": "custom tag type", - "icon": null - }, - "preData": null, - "tags": [], - "featureName": null, - "project": null, - "environment": null -} -``` - -### `drop-tag-types` - -This event fires when you drop all existing tag types as part of a configuration import. The `data.name` property will always be `"all-tag-types"`. - -```json title="example event: drop-tag-types" -{ - "id": 38, - "type": "drop-tag-types", - "createdBy": "import-API-token", - "createdAt": "2022-06-03T11:30:40.596Z", - "data": { - "name": "all-tag-types" - }, - "preData": null, - "tags": [], - "featureName": null, - "project": null, - "environment": null -} -``` - -## Integration events - -### `addon-config-created` - -This event fires when you create an integration configuration. The `data` property contains the provider type. - -```json title="example event: addon-config-created" -{ - "id": 960, - "type": "addon-config-created", - "createdBy": "user@company.com", - "createdAt": "2022-06-03T10:15:45.040Z", - "data": { - "provider": "webhook" - }, - "preData": null, - "tags": [], - "featureName": null, - "project": null, - "environment": null -} -``` - -### `addon-config-updated` - -This event fires when you update an integration configuration. The `data` property contains the integration's ID and provider type. - -```json title="example event: addon-config-updated" -{ - "id": 961, - "type": "addon-config-updated", - "createdBy": "user@company.com", - "createdAt": "2022-06-03T10:16:11.732Z", - "data": { - "id": "2", - "provider": "webhook" - }, - "preData": null, - "tags": [], - "featureName": null, - "project": null, - "environment": null -} -``` - -### `addon-config-deleted` - -This event fires when you update an integration configuration. The `data` property contains the integration's ID. - -```json title="example event: addon-config-deleted" -{ - "id": 964, - "type": "addon-config-deleted", - "createdBy": "user@company.com", - "createdAt": "2022-06-03T10:16:59.723Z", - "data": { - "id": "2" - }, - "preData": null, - "tags": [], - "featureName": null, - "project": null, - "environment": null -} -``` - -## User events - -### `user-created` - -This event fires when you create a new user. The `data` property contains the user's information. - -```json title="example event: user-created" -{ - "id": 965, - "type": "user-created", - "createdBy": "user@company.com", - "createdAt": "2022-06-03T10:23:47.713Z", - "data": { - "id": 44, - "name": "New User Name", - "email": "newuser@company.com" - }, - "preData": null, - "tags": [], - "featureName": null, - "project": null, - "environment": null -} -``` - -### `user-updated` - -This event fires when you update a user. The `data` property contains the updated user information; the `preData` property contains the previous state of the user's information. - -```json title="example event: user-updated" -{ - "id": 967, - "type": "user-updated", - "createdBy": "user@company.com", - "createdAt": "2022-06-03T10:24:26.301Z", - "data": { - "id": 44, - "name": "New User's Name", - "email": "newuser@company.com" - }, - "preData": { - "id": 44, - "name": "New User Name", - "email": "newuser@company.com" - }, - "tags": [], - "featureName": null, - "project": null, - "environment": null -} -``` - -### `user-deleted` - -This event fires when you delete a user. The `preData` property contains the deleted user's information. - -```json title="example event: user-deleted" -{ - "id": 968, - "type": "user-deleted", - "createdBy": "user@company.com", - "createdAt": "2022-06-03T10:24:49.153Z", - "data": null, - "preData": { - "id": 44, - "name": "New User's Name", - "email": "newuser@company.com" - }, - "tags": [], - "featureName": null, - "project": null, - "environment": null -} -``` - -## Environment events - -### `environment-import` - -This event fires when you import an environment (custom or otherwise) as part of an import job. The `data` property contains the configuration of the imported environment. - -```json title="example event: environment-import" -{ - "id": 24, - "type": "environment-import", - "createdBy": "import-API-token", - "createdAt": "2022-06-03T11:30:40.557Z", - "data": { - "name": "custom-environment", - "type": "test", - "sortOrder": 9999, - "enabled": true, - "protected": false - }, - "preData": null, - "tags": [], - "featureName": null, - "project": null, - "environment": null -} -``` - -### `drop-environments` - -This event fires when you delete existing environments as part of an import job. The `data.name` property will always be `"all-environments"`. - -```json title="example event: drop-environments" -{ - "id": 21, - "type": "drop-environments", - "createdBy": "import-API-token", - "createdAt": "2022-06-03T11:30:40.549Z", - "data": { - "name": "all-projects" - }, - "preData": null, - "tags": [], - "featureName": null, - "project": null, - "environment": null -} -``` - -## Segment events - -### `segment-created` - -This event fires when you create a segment. The `data` property contains the newly created segment. - -```json title="example event: segment-created" -{ - "id": 969, - "type": "segment-created", - "createdBy": "user@company.com", - "createdAt": "2022-06-03T10:29:43.977Z", - "data": { - "id": 5, - "name": "new segment", - "description": "this segment is for events", - "constraints": [ - { - "values": ["appA", "appB", "appC"], - "inverted": false, - "operator": "IN", - "contextName": "appName", - "caseInsensitive": false - } - ], - "createdBy": "user@company.com", - "createdAt": "2022-06-03T10:29:43.974Z" - }, - "preData": null, - "tags": [], - "featureName": null, - "project": null, - "environment": null -} -``` - -### `segment-updated` - -This event fires when you update a segment's configuration. The `data` property contains the new segment configuration; the `preData` property contains the previous segment configuration. - -```json title="example event: segment-updated" -{ - "id": 970, - "type": "segment-updated", - "createdBy": "user@company.com", - "createdAt": "2022-06-03T10:29:59.892Z", - "data": { - "id": 5, - "name": "new segment", - "description": "this segment is for events", - "constraints": [], - "createdBy": "user@company.com", - "createdAt": "2022-06-03T10:29:43.974Z" - }, - "preData": { - "id": 5, - "name": "new segment", - "createdAt": "2022-06-03T10:29:43.974Z", - "createdBy": "user@company.com", - "constraints": [ - { - "values": ["appA", "appB", "appC"], - "inverted": false, - "operator": "IN", - "contextName": "appName", - "caseInsensitive": false - } - ], - "description": "this segment is for events" - }, - "tags": [], - "featureName": null, - "project": null, - "environment": null -} -``` - -### `segment-deleted` - -This event fires when you delete a segment. - -```json title="example event: segment-deleted" -{ - "id": 971, - "type": "segment-deleted", - "createdBy": "user@company.com", - "createdAt": "2022-06-03T10:30:08.128Z", - "data": {}, - "preData": null, - "tags": [], - "featureName": null, - "project": null, - "environment": null -} -``` - -## Suggest changes events - -### `suggest-change-created` - -This event fires when you create a change-request draft. - -```json title="example event: suggest-change-created" -{ - "id": 971, - "type": "suggest-change-created", - "createdBy": "user@company.com", - "createdAt": "2022-06-03T10:30:08.128Z", - "data": {}, - "preData": null, - "tags": [], - "featureName": null, - "project": null, - "environment": null -} -``` diff --git a/website/docs/reference/events.mdx b/website/docs/reference/events.mdx new file mode 100644 index 0000000000..772b4a5407 --- /dev/null +++ b/website/docs/reference/events.mdx @@ -0,0 +1,725 @@ +--- +title: Events +--- + +## Overview + +Events help you keep track of changes across your Unleash instance. You can explore events in [Event Log](#event-log) or using the global [Event Timeline](#event-timeline). + +The Event Log provides a full list of all events, whereas the Event Timeline offers a highlight of recent key events and [Signals](/reference/signals) from external sources. +You can use Event Log for auditing purposes, while Event Timeline is particularly helpful for debugging recent changes and their impact. + +## Event Log + +The Event Log lists all events in your Unleash instance. You can search and filter events by date range, event type, project, feature flag, and user. You can also export events as CSV or JSON files. + +To access events in the Admin UI, you need Admin access. To view all events, go to **Admin > Event log**. To view events for a specific feature flag, go to the **Event log** tab on that feature flag's page. + +Each [event type](#event-types) contains different data, but all events follow the same schema: + + +| Field | Type | Description | +|--------------------|--------|-------------------------------------------------------------------| +| `id`* | number | Unique identifier for the event; incremental whole number. | +| `type`* | string | Describes the type of event (e.g., `feature-strategy-update`). | +| `createdAt`* | string | Timestamp when the event was created; ISO 8601 format. | +| `createdBy`* | string | Email of the user who triggered the event. | +| `createdByUserId` | number | Unique identifier of the user who triggered the event. | +| `data` | object | Details about the event (e.g., feature strategy, API token data). | +| `preData` | object | Previous state before the event. | +| `tags` | array | Array of tags associated with the event. | +| `featureName` | string | Name of the feature flag associated with the event. | +| `project` | string | Name of the project involved in the event. | +| `environment` | string | Environment related to the event (e.g., `development`). | +| `label` | string | Brief description of the event. | +| `summary` | string | Markdown formatted summary of the event. | + + +Fields marked with an asterisk (*) are always returned in the event schema. Other fields may be optional or have null values, depending on the event type. + +See the [feature-created event type](#feature-created) for an example event. + + +## Event Timeline + +:::note Availability + +**Plan**: [Enterprise](https://www.getunleash.io/plans/enterprise) | **Version**: `6.3+` in BETA + +::: + +Event Timeline highlights recent events across all your projects in one unified timeline. You can access the timeline from the top menu in the Admin UI. + +![Event timeline in Unleash Admin UI](/img/event-timeline.png) + +The timeline shows key events and signals for up to 48 hours per environment and is designed to help you get an overview of changes and quickly identify and debug any issues. You can switch between different time spans to focus on recent activity. +Although you can filter events by environment, the timeline also shows environment-agnostic events, such as archiving a feature flag. + +You can enable or disable the timeline view at any time based on your preferences. Events that occur close together in time are automatically grouped, but hovering over an event group shows detailed information about the specific events. + +## Event types + +### Feature flag events + +Events related to feature flags and their life cycle. + +#### `feature-created` + +Generated when you create a feature flag. The `data` property contains the details for the new feature flag. + +```json +{ + "id": 27332, + "type": "feature-created", + "createdBy": "user@getunleash.io", + "createdAt": "2024-10-03T11:09:53.225Z", + "createdByUserId": 110, + "data": { + "name": "test-flag", + "description": null, + "type": "release", + "project": "test-project", + "stale": false, + "createdAt": "2024-10-03T11:09:53.201Z", + "lastSeenAt": null, + "impressionData": false, + "archivedAt": null, + "archived": false + }, + "preData": null, + "tags": [], + "featureName": "test-flag", + "project": "test-project", + "environment": null, + "label": "Flag created", + "summary": "**user@getunleash.io** created **test-flag** in ... " +} +``` + +#### `feature-deleted` + +Generated when you delete a feature flag. The `preData` property contains the deleted feature flag data. + +#### `feature-archived` + +Generated when you archive a feature flag. `preData` and `data` are null. + +#### `feature-revived` + +Generated when you revive an archived feature flag. `preData` and `data` are null. + +#### `feature-metadata-updated` + +Generated when a feature flag's metadata, such as description, flag type, or impression data settings, are changed. The `data` property contains the new flag data. The `preData` property contains the flag's previous data. + +#### `feature-project-change` + +Generated when you move a feature flag from one project to another. The `data` property contains the names of the old and the new project. + +```json +{ + "id": 27332, + "type": "feature-project-change", + "createdBy": "user@getunleash.io", + "createdAt": "2024-10-03T11:09:53.225Z", + "createdByUserId": 110, + "data": { + "newProject": "test-project", + "oldProject": "old-test-project" + }, + "preData": null, + "tags": [], + "featureName": "test-flag", + "project": "test-project", + "environment": null, + "label": "Flag moved to a new project", + "summary": "**user@getunleash.io** moved **test-flag** from ... " +} +``` + +#### `feature-import` + +Generated when you import a feature flag as part of an import process. The `data` property contains the feature flag data. See [feature-created](#feature-created) for an example. + +#### `feature-tagged` + +Generated when you add a tag to a feature flag. The `data` property contains the new tag. + +```json +{ + "id": 27333, + "type": "feature-tagged", + "createdBy": "user@getunleash.io", + "createdAt": "2024-10-03T11:09:53.225Z", + "createdByUserId": 110, + "data": { + "type": "simple", + "value": "tag2" + }, + "preData": null, + "tags": [ + { + "type": "simple", + "value": "tag2" + } + ], + "featureName": "test-flag", + "project": "test-project", + "environment": null, + "label": "Flag tagged", + "summary": "**user@getunleash.io** tagged **test-flag** with ... " +} +``` + +#### `feature-untagged` + +Generated when you remove a tag from a feature flag. The `data` property contains the tag that was removed. See [feature-tagged](#feature-tagged) for an example. + +#### `feature-tag-import` + +Generated when you import a tagged feature flag as part of an import job. The `data` property contains the name of the feature and the tag. + +```json +{ + "id": 27334, + "type": "feature-tag-import", + "createdBy": "user@getunleash.io", + "createdAt": "2024-10-03T11:09:53.225Z", + "createdByUserId": 110, + "data": { + "featureName": "new-feature", + "tag": { + "type": "simple", + "value": "tag1" + } + }, + "preData": null, + "tags": [], + "featureName": null, + "project": null, + "environment": null, + "label": null, + "summary": null +} +``` + +#### `feature-strategy-add` + +Generated when you add a strategy to a feature flag. The `data` property contains the configuration for the new strategy. + +```json +{ + "id": 27335, + "type": "feature-strategy-add", + "createdBy": "user@getunleash.io", + "createdAt": "2024-10-03T11:09:53.225Z", + "createdByUserId": 110, + "data": { + "id": "3f4bf713-696c-43a4-8ce7-d6c607108858", + "name": "flexibleRollout", + "title": null, + "disabled": false, + "parameters": { + "groupId": "new-feature", + "rollout": "67", + "stickiness": "default" + }, + "variants": [], + "sortOrder": 0, + "segments": [] + }, + "preData": null, + "tags": [], + "featureName": "new-feature", + "project": "my-other-project", + "environment": "default", + "label": "Flag strategy added", + "summary": "**user@getunleash.io** added strategy" +} +``` + +#### `feature-strategy-update` + +Generated when you update a feature flag strategy. The `data` property contains the new strategy configuration. The `preData` property contains the previous strategy configuration. + +#### `feature-strategy-remove` + +Generated when you remove a strategy from a feature flag. The `preData` contains the configuration of the strategy that was removed. + + +#### `feature-stale-on` + +Generated when you mark a feature flag as stale. `preData` and `data` are null. + +#### `feature-stale-off` + +Generated when you mark a stale feature flag as no longer stale. `preData` and `data` are null. + +#### `feature-environment-enabled` + +Generated when you enable an environment for a feature flag. The `environment` property contains the name of the environment, `preData` and `data` are null. + +#### `feature-environment-disabled` + +Generated when you disable an environment for a feature. The `environment` property contains the name of the environment. `preData` and `data` are null. + +#### `drop-features` + +Generated when you delete existing features as part of an import job. The `data.name` property is `"all-features"`. + +```json +{ + "id": 27336, + "type": "drop-features", + "createdBy": "user@getunleash.io", + "createdAt": "2024-10-03T11:09:53.225Z", + "createdByUserId": 110, + "data": { + "name": "all-features" + }, + "preData": null, + "tags": [], + "featureName": null, + "project": null, + "environment": null +} +``` + +#### `drop-feature-tags` + +Generated when you drop all existing tags as part of a configuration import. The `data.name` is `"all-feature-tags"`. See [drop-features](#drop-features) for an example. + +#### `feature-potentially-stale-on` + +Generated when Unleash marks a feature flag as potentially stale due to exceeding the expected lifetime of its [feature flag type](/reference/feature-toggle-types). `preData` and `data` are null. + +#### `feature-updated` + +:::caution Deprecated functionality + +Deprecated in Unleash 4.3. Use more granular events, such as `feature-strategy-update`, instead. + +::: + +### Strategy events + +#### `strategy-created` + +Generated when you create a strategy. The `data` property contains the strategy configuration. + +```json +{ + "id": 273357, + "type": "strategy-created", + "createdBy": "user@getunleash.io", + "createdAt": "2024-10-03T11:09:53.225Z", + "createdByUserId": 110, + "data": { + "name": "new-strategy", + "description": "this strategy does ...", + "parameters": [], + "editable": true, + "deprecated": false + }, + "preData": null, + "tags": [], + "featureName": null, + "project": null, + "environment": null, + "label": "strategy-created", + "summary": "**user@getunleash.io** triggered **strategy-created**" +} +``` + +#### `strategy-updated` + +Generated when you change a strategy's configuration. The `data` property contains the new strategy configuration. See [strategy-created](#strategy-created) for an example. + +#### `strategy-deleted` + +Generated when you delete a strategy. The `data` property contains the name of the deleted strategy, `preData` is null. + +#### `strategy-deprecated` + +Generated when you deprecate a strategy. The `data` property contains the name of the deprecated strategy, `preData` is null. + +#### `strategy-reactivated` + +Generated when you reactivate a deprecated strategy. The `data` property contains the name of the reactivated strategy, `preData` is null. + +#### `strategy-import` + +Generated when you import a strategy as part of an import job. The `data` property contains the strategy's configuration, `preData` is null. See [strategy-created](#strategy-created) for an example. + +#### `drop-strategies` + +Generated when you delete existing strategies as part of an import job. The `data.name` property is `"all-strategies"`. + +```json +{ + "id": 27338, + "type": "drop-strategies", + "createdBy": "import-API-token", + "createdAt": "2022-06-03T11:30:40.579Z", + "data": { + "name": "all-strategies" + }, + "preData": null, + "tags": [], + "featureName": null, + "project": null, + "environment": null +} +``` + +### Context field events + +#### `context-field-created` + +Generated when you create a context field. The `data` property contains the context field configuration. + +```json +{ + "id": 27339, + "type": "context-field-created", + "createdBy": "user@getunleash.io", + "createdAt": "2024-10-03T11:09:53.225Z", + "createdByUserId": 110, + "data": { + "name": "new-context-field", + "description": "this context field is for describing events", + "legalValues": [], + "stickiness": false + }, + "preData": null, + "tags": [], + "featureName": null, + "project": null, + "environment": null, + "label": "Context field created", + "summary": "**user@getunleash.io** created context field **new-context-field**" +} +``` + +#### `context-field-updated` + +Generated when you update a context field. The `data` property contains the new context field configuration. See [context-field-created](#context-field-created) for an example. + +#### `context-field-deleted` + +Generated when you delete a context field. The `data` property contains the name of the deleted context field. + +### Project events + +#### `project-created` + +Generated when you create a project. The `data` property contains the project configuration. + +```json +{ + "id": 27340, + "type": "project-created", + "createdBy": "user@getunleash.io", + "createdAt": "2024-10-03T11:09:53.225Z", + "createdByUserId": 110, + "data": { + "id": "my-other-project", + "name": "my other project", + "description": "a project for important work", + "defaultStickiness": "default", + "mode": "private", + "changeRequestEnvironments": [] + }, + "preData": null, + "tags": [], + "featureName": null, + "project": "my-other-project", + "environment": null, + "label": "Project created", + "summary": "**user@getunleash.io** created project **my-other-project** ..." +} +``` + +#### `project-updated` + +Generated when you update a project's configuration. The `data` property contains the new project configuration. The `preData` property contains the previous project configuration. + +#### `project-deleted` + +Generated when you delete a project. The `project` property contains the name of the deleted project. + +#### `project-import` + +Generated when you import a project. The `data` property contains the project's configuration details. See [project-created](#project-created) for an example. + +#### `drop-projects` + +Generated when you delete existing projects as part of an import job. The `data.name` property is `"all-projects"`. + +### Tag events + +#### `tag-created` + +Generated when you create a new tag. The `data` property contains the tag that was created. + +```json +{ + "id": 27341, + "type": "tag-created", + "createdBy": "user@getunleash.io", + "createdAt": "2024-10-03T11:09:53.225Z", + "createdByUserId": 110, + "data": { + "type": "6.1.0", + "value": "release" + }, + "preData": null, + "tags": [], + "featureName": null, + "project": null, + "environment": null, + "label": "tag-created", + "summary": "**user@getunleash.io** triggered **tag-created**" +} +``` + +#### `tag-deleted` + +Generated when you delete a tag. The `data` property contains the tag that was deleted. See [tag-created](#tag-created) for an example. + +#### `tag-import` + +Generated when you import a tag as part of an import job. The `data` property contains the imported tag. See [tag-created](#tag-created) for an example. + +#### `drop-tags` + +Generated when you delete existing tags as part of an import job. The `data.name` property is `"all-tags"`. + +```json +{ + "id": 27342, + "type": "drop-tags", + "createdBy": "user@getunleash.io", + "createdAt": "2024-10-03T11:09:53.225Z", + "createdByUserId": 110, + "data": { + "name": "all-tags" + }, + "preData": null, + "tags": [], + "featureName": null, + "project": null, + "environment": null, + "label": "drop-tags", + "summary": "**user@getunleash.io** triggered **drop-tags**" +} +``` + +### Tag type events + +#### `tag-type-created` + +Generated when you create a new tag type. The `data` property contains the tag type configuration. + +```json +{ + "id": 27343, + "type": "tag-type-created", + "createdBy": "user@getunleash.io", + "createdAt": "2024-10-03T11:09:53.225Z", + "createdByUserId": 110, + "data": { + "name": "new-tag-type", + "description": "event testing" + }, + "preData": null, + "tags": [], + "featureName": null, + "project": null, + "environment": null, + "label": "tag-type-created", + "summary": "**user@getunleash.io** triggered **tag-type-created**" +} +``` + +#### `tag-type-updated` + +Generated when you update a tag type. The `data` property contains the new tag type configuration. See [tag-type-created](#tag-type-created) for an example. + +#### `tag-type-deleted` + +Generated when you delete a tag type. The `data` property contains the name of the deleted tag type. + +#### `tag-type-import` + +Generated when you import a tag type as part of an import job. The `data` property contains the imported tag. See [tag-type-created](#tag-type-created) for an example. + +#### `drop-tag-types` + +Generated when you drop all existing tag types as part of a configuration import. The `data.name` property is `"all-tag-types"`. + +### Integration events + +#### `addon-config-created` + +Generated when you create an integration configuration. The `data` property contains the provider type. + +```json +{ + "id": 27343, + "type": "addon-config-created", + "createdBy": "user@getunleash.io", + "createdAt": "2024-10-03T11:09:53.225Z", + "createdByUserId": 110, + "data": { + "id": 14, + "provider": "webhook", + "enabled": true, + "description": "Test Webhooks", + "events": [ + "feature-updated" + ], + "projects": [ + "test-project" + ], + "environments": [ + "production" + ] + }, + "preData": null, + "tags": [], + "featureName": null, + "project": null, + "environment": null, + "label": "Integration configuration created", + "summary": "**user@getunleash.io** created a new **webhook** integration configuration" +} +``` + +#### `addon-config-updated` + +Generated when you update an integration configuration. The `data` property contains the `id` and `provider` of the integration. + + +#### `addon-config-deleted` + +Generated when you delete an integration configuration. The `data` property contains the `id` of the integration. + +### User events + +#### `user-created` + +Generated when you create a new user. The `data` property contains the user's information. + +```json +{ + "id": 27344, + "type": "user-created", + "createdBy": "user@getunleash.io", + "createdAt": "2024-10-03T11:09:53.225Z", + "createdByUserId": 110, + "data": { + "id": 111, + "name": "New User Name", + "email": "newuser@getunleash.io", + "rootRole": 2 + }, + "preData": null, + "tags": [], + "featureName": null, + "project": null, + "environment": null, + "label": "User created", + "summary": "**user@getunleash.io** created user **New User Name**" +} +``` + +#### `user-updated` + +Generated when you update a user. The `data` property contains the updated user information; the `preData` property contains the previous state of the user's information. + + +#### `user-deleted` + +Generated when you delete a user. The `preData` property contains the deleted user's information. + +### Environment events + +#### `environment-import` + +Generated when you import an environment as part of an import job. The `data` property contains the configuration of the imported environment. + +```json +{ + "id": 27345, + "type": "environment-import", + "createdBy": "import-API-token", + "createdAt": "2022-06-03T11:30:40.557Z", + "data": { + "name": "custom-environment", + "type": "test", + "sortOrder": 9999, + "enabled": true, + "protected": false + }, + "preData": null, + "tags": [], + "featureName": null, + "project": null, + "environment": null +} +``` + +#### `drop-environments` + +Generated when you delete existing environments as part of an import job. The `data.name` property is `"all-environments"`. + + +### Segment events + +#### `segment-created` + +Generated when you create a segment. The `data` property contains the newly created segment. + +```json +{ + "id": 27346, + "type": "segment-created", + "createdBy": "user@getunleash.io", + "createdAt": "2024-10-03T11:09:53.225Z", + "createdByUserId": 110, + "data": { + "id": 5, + "name": "new segment", + "description": "this segment is for events", + "project": "development", + "constraints": [ + { + "values": ["appA", "appB", "appC"], + "inverted": false, + "operator": "IN", + "contextName": "appName", + "caseInsensitive": false + } + ], + "createdBy": "user@getunleash.io", + "createdAt": "2024-10-03T11:09:53.225Z" + }, + "preData": null, + "tags": [], + "featureName": null, + "project": "development", + "environment": null, + "label": "Segment created", + "summary": "**user@getunleash.io** created segment **new segment**" +} +``` + +#### `segment-updated` + +Generated when you update a segment's configuration. The `data` property contains the new segment configuration; the `preData` property contains the previous segment configuration. + + +#### `segment-deleted` + +Generated when you delete a segment. `preData` property contains the deleted segment. diff --git a/website/docs/reference/integrations/datadog.md b/website/docs/reference/integrations/datadog.md index 15eac19a01..16488cd696 100644 --- a/website/docs/reference/integrations/datadog.md +++ b/website/docs/reference/integrations/datadog.md @@ -67,7 +67,7 @@ The body template property is available from **Unleash 5.6** onwards. ::: -- **Body template** - This is an optional property. The template is used to override the body template used by Unleash when performing the HTTP POST. You can format your message using a [Mustache template](https://mustache.github.io). Refer to the [Unleash event types](/reference/event-types) reference to find out which event properties you have access to in the template. +- **Body template** - This is an optional property. The template is used to override the body template used by Unleash when performing the HTTP POST. You can format your message using a [Mustache template](https://mustache.github.io). Refer to the [Unleash event types](/reference/events#event-types) reference to find out which event properties you have access to in the template. Example: diff --git a/website/docs/reference/service-accounts.md b/website/docs/reference/service-accounts.md index e4288caf46..0fcea41c3a 100644 --- a/website/docs/reference/service-accounts.md +++ b/website/docs/reference/service-accounts.md @@ -26,7 +26,7 @@ Service account tokens allow service accounts to use the Admin API as themselves These tokens act just like [personal access tokens](./api-tokens-and-client-keys.mdx#personal-access-tokens) for the service accounts, except that they are managed by Unleash admins. -When using a service account token to modify resources, the event log will display the service account name for that operation. +When you use a service account token to modify resources, the events record the service account name for that operation. Service account tokens can be managed by editing the respective service account: diff --git a/website/docusaurus.config.js b/website/docusaurus.config.js index 8d5a849ca5..4394be6d2a 100644 --- a/website/docusaurus.config.js +++ b/website/docusaurus.config.js @@ -336,11 +336,19 @@ module.exports = { }, { from: '/advanced/audit_log', - to: '/reference/event-log', + to: '/reference/events', }, { - from: '/api/open_api', - to: '/reference/api/unleash', + from: '/advanced/audit_log', + to: '/reference/events', + }, + { + from: '/reference/event-log', + to: '/reference/events', + }, + { + from: '/reference/event-types', + to: '/reference/events', }, { from: '/advanced/api_access', diff --git a/website/sidebars.js b/website/sidebars.js index 388cae67db..9153993944 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -324,8 +324,7 @@ module.exports = { 'reference/custom-activation-strategies', 'reference/dependent-features', 'reference/environments', - 'reference/event-log', - 'reference/event-types', + 'reference/events', 'reference/feature-flag-naming-patterns', 'reference/feature-lifecycle', 'reference/feature-toggles', diff --git a/website/static/img/event-timeline.png b/website/static/img/event-timeline.png new file mode 100644 index 0000000000000000000000000000000000000000..d1b14e85e0db7f618f43aa63b9da7cb5e33f125c GIT binary patch literal 63440 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

SA`aY(}GD~UDud=yOe)E+H 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