Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flag trigger + audit logs #39

Merged
merged 32 commits into from
Jan 22, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
e174528
docs: creates the trigger page
htessaro Jan 14, 2024
e6f6fc6
docs: update flags index page and trigger page.
htessaro Jan 15, 2024
b3d0255
docs: add test a trigger to the trigger page
htessaro Jan 15, 2024
9dfd8c9
docs: add audit logs page
htessaro Jan 16, 2024
d64780b
docs: update sidebar organization
htessaro Jan 16, 2024
55799de
feat: start creating Glossary component
htessaro Jan 16, 2024
b6d13f8
docs: Update audit log and triggers solving comments
htessaro Jan 17, 2024
0c3ecb3
doc: update triggers (accept suggestion)
htessaro Jan 18, 2024
75e54d9
doc: update triggers (accept suggestion)
htessaro Jan 18, 2024
2afb580
doc: update triggers (accept suggestion)
htessaro Jan 18, 2024
986f3ee
doc: update triggers (accept suggestion)
htessaro Jan 18, 2024
39c8f77
doc: update triggers (accept suggestion)
htessaro Jan 18, 2024
6fa95f8
doc: update triggers (accept suggestion)
htessaro Jan 18, 2024
2b6801f
doc: update the home page (integrate trigger content)
htessaro Jan 18, 2024
7ca51f0
doc: update the audit log page
htessaro Jan 18, 2024
a907241
doc: update the trigger page
htessaro Jan 18, 2024
7eb75ac
Merge branch 'flag-trigger' of https://github.com/writechoiceorg/buck…
htessaro Jan 18, 2024
81b8911
doc: update audit-log (accept suggestions)
htessaro Jan 19, 2024
be3a0b8
doc: update audit-log (accept suggestions)
htessaro Jan 19, 2024
be1dd4c
doc: update audit-log (accept suggestions)
htessaro Jan 19, 2024
ec78af0
doc: update triggers (accept suggestion)
htessaro Jan 19, 2024
0e578ae
doc: update triggers (accept suggestion)
htessaro Jan 19, 2024
a82c245
doc: update triggers (accept suggestion)
htessaro Jan 19, 2024
69b8642
doc: update triggers (accept suggestion)
htessaro Jan 19, 2024
f0768dd
doc: update triggers (accept suggestion)
htessaro Jan 19, 2024
72d6560
doc: update trigger image
htessaro Jan 19, 2024
fa1dd8a
Merge branch 'flag-trigger' of https://github.com/writechoiceorg/buck…
htessaro Jan 19, 2024
a132d79
docs: update audit logs images
htessaro Jan 19, 2024
b24aa30
fix: fix sidebar and navbar css
htessaro Jan 19, 2024
2a5b9c3
style: change detail decoration color to Bucketeer branding
htessaro Jan 19, 2024
3e393f8
style: update datails border
htessaro Jan 19, 2024
67f9628
style: updates the detais design
htessaro Jan 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
630 changes: 630 additions & 0 deletions docs/feature-flags/audit-logs.mdx

Large diffs are not rendered by default.

114 changes: 114 additions & 0 deletions docs/feature-flags/creating-feature-flags/trigger.mdx
htessaro marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
---
title: Triggers
# sidebar_position:
slug: /feature-flags/creating-feature-flags/triggers
description: Use the flag triggers to automatically turn feature flags on or off by calling a URL using the POST method.
tags: ['guide', 'automation', 'trigger', 'feature-flag']
---

import CenteredImg from '@site/src/components/centered-img/CenteredImg';

Flag triggers are a feature that Bucketeer provides to let you change the flag's state (ON/OFF) by calling a URL. As a result, you can use this option to enable or disable flags during CI/CD (Continuous Integration/Continuous Deployment) pipelines or based on an APM (Application Performance Monitoring) integration.

To access the trigger page on the Bucketeer dashboard, select the **Feature Flags** tab, choose the desired flag, and click on its name. Select the **Trigger** tab at the top of the new page. You can check the existing triggers related to the current feature flag.
htessaro marked this conversation as resolved.
Show resolved Hide resolved

## How to use triggers

You can use the trigger feature to automate the remote flag's state control using Webhook URLs. You can integrate triggers with any tool capable of performing a POST request, enabling you to activate or deactivate flags based on specific operational health thresholds or when you receive specific alerts. You can link each flag to one or more triggers used by one or more tools or alert systems.
htessaro marked this conversation as resolved.
Show resolved Hide resolved

One common integration of triggers is with APM solutions, such as:

- [Datadogs](https://www.datadoghq.com/)
- [New Relic One](https://newrelic.com/)
- [Honeycomb](https://www.honeycomb.io/)
- [Dynatrace](https://www.dynatrace.com/)
- [Splunk Observability Cloud](https://www.splunk.com/en_us/products/observability.html)

APMs can automatically modify the flag state based on certain conditions within that platform. Typically, APMs use triggers to shut down flags in pre-configured scenarios. For example, you can use an APM to monitor your system. If the error rate reaches 5%, the APM will call the trigger URL to disable (modify to OFF state) the feature flag.

CI/CD pipelines can also take advantage of flag triggers. You can use triggers when deploying code changes to turn a flag on or off automatically at the final stage of the pipeline. In addition, you can create your own automation algorithm and use triggers to control the flags in your application.

## Create a triggers

The creation of triggers is a straightforward process. Follow the steps below:
htessaro marked this conversation as resolved.
Show resolved Hide resolved

1. Access **Trigger** tab.
htessaro marked this conversation as resolved.
Show resolved Hide resolved
2. Click **+ Add Trigger**.
3. Select the **Trigger type**. Currently, only the **Webhook** type is available.
htessaro marked this conversation as resolved.
Show resolved Hide resolved
4. Choose the **Action** the trigger will perform. You can choose between turning the flag ON or OFF.
5. Provide a description for the trigger. It's optional. However, the Bucketter team recommends always providing clear descriptions for easy maintenance.
6. Click **Submit**.

A new trigger will be displayed as in the image below, providing the **Trigger URL**. You should copy and save the Trigger URL to use in your application.
htessaro marked this conversation as resolved.
Show resolved Hide resolved

<CenteredImg
imgURL="img/feature-flags/trigger/flag-trigger.png"
/>

:::info Copy and save the Trigger URL
htessaro marked this conversation as resolved.
Show resolved Hide resolved

When you create a trigger, you will receive a Trigger URL. It's important to copy and store the URL in a safe place or use it directly on your APM. Once you leave the Trigger page, the URL cannot be recovered. If you access the Trigger page, the existing trigger URLs are limited to only five characters, which are displayed to enable you to identify each trigger.

:::

The Trigger URL includes the authentication token, so all you need to do to activate the trigger is to perform a POST request using the Trigger URL. You must keep the Trigger URL safe and secure, as it contains sensitive information. Anyone with access to the Trigger URL can modify the state of your system flag.

:::warning Trigger URL linkage

In the event of a Trigger URL leak, the Bucketeer team strongly recommends that you immediately reset or delete the trigger. Otherwise, anyone with the Trigger URL can modify the state of your application.

:::

### Usage recomendations

When using Bucketeer, it's important to note that triggers don't receive any information from the Webhook request body. In simpler terms, all you need to do to execute a trigger is perform a POST request to the Trigger URL you received when creating the trigger. As a result, Bucketeer is unable to identify the source of the POST request. Therefore, if you're using different tools to manage the flag remotely, it's recommended that you create a distinct trigger for each tool. Doing this lets you easily identify the source of a flag turn-off.

:::note Future releases

Bucketeer has in its roadmap the objective to accept payloads in the Webhook body to enable you to provide additional information regarding the request source. Stay tuned for future releases.

:::

## Manage triggers

When you access the Trigger tab, you will have access to all existing triggers related to the current flag. The image provides an example of a flag associated with three triggers.

<CenteredImg
imgURL="img/feature-flags/trigger/flag-trigger-existing-triggers.png"
/>

Each trigger presents the following information:

- **Action**: Specify if the trigger turns the flag ON or OFF when activated.
- **Trigger URL**: Part of the Trigger URL. As mentioned before, you only have access to the complete trigger URL at the time of trigger creation.
- **Triggered Times**: Inform the number of times the trigger was used and the associated action was performed.
- **Last Triggered**: Inform the date and time the trigger was last used.

:::info Triggered execution

The Triggered Times and Last Triggered will only be updated if the trigger action changes the flag state. For instance, if the flag was initially ON, and the trigger was executed to turn it OFF, then the Triggered Times and Last Triggered will be updated. However, suppose the flag was initially OFF, and the trigger action was also intended to turn it OFF. In that case, there will be no changes to the Triggered Times and Last Triggered because the flag state was not changed.
htessaro marked this conversation as resolved.
Show resolved Hide resolved

:::

After creating a trigger, you can perform four actions on it through the Bucketeer dashboard by clicking on the ellipsis (**...**) located at the top right corner of the trigger card:
htessaro marked this conversation as resolved.
Show resolved Hide resolved

- **Edit**: Use this option to update the trigger description.
- **Disable**: Deactivate the trigger without removing or changing the Trigger URL. Despite receiving a POST request, the Bucketeer system will not execute the trigger action when disabled.
- **Reset**: Create a new Trigger URL. POST requests using the old Trigger URL will not change the flag state. When you Reset the trigger, the Bucketeer system will provide a new Trigger URL. You should copy and save the Trigger URL to use in your application.
- **Delete**: Remove the trigger.

:::info Reset operation

Resetting a trigger does not restart Triggered Times and Last Triggered information.
htessaro marked this conversation as resolved.
Show resolved Hide resolved

A new field shows up on the trigger card, informing the date of the last reset.
htessaro marked this conversation as resolved.
Show resolved Hide resolved

:::

## Test a trigger

You can make a POST request using the Trigger URL to test a trigger. The code block below presents an example of the code used to perform a request using `curl`:

```curl
https://dev.bucketeer.jp/webhook/MTQyMDY5OTI0ODc2MQw4yPzGndlkezFEsZE_uPnA
htessaro marked this conversation as resolved.
Show resolved Hide resolved
```
9 changes: 3 additions & 6 deletions docs/feature-flags/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ This section presents the necessary information to use Bucketeer feature flags.
- [Create a feature flag](../feature-flags/creating-feature-flags/create-feature-flag): Learn how to create flags and define their properties.
- [Targeting with feature flags](../feature-flags/creating-feature-flags/targeting): Discover how to target specific users or groups with your flags based on various attributes.
- [Manage variations](../feature-flags/creating-feature-flags/manage-variations): Understand how to manage and configure different variations of your feature flags.
- [Trigger flags](../feature-flags/creating-feature-flags/trigger.mdx): Use Webhooks to remotely manage flags by turning them ON or OFF.
- [Auto operation](../feature-flags/creating-feature-flags/auto-operation): Automate the feature flag operation.
- [Evaluate results](../feature-flags/creating-feature-flags/evaluate-results): Explore how to evaluate and analyze the usage of your flags.
- [Other flag settings](../feature-flags/creating-feature-flags/settings-and-history): Explore additional settings and options for your flags.
Expand All @@ -19,10 +20,6 @@ This section presents the necessary information to use Bucketeer feature flags.

The [API keys](/feature-flags/api-keys) describe what they're and how they're used to authenticate and control access to the Bucketeer system.

## Testing with flags
## Audit logs

The [Testing with flags](../feature-flags/testing-with-flags) will cover the three components used to perform tests on the Bucketeer system:

- [Goals](../feature-flags/testing-with-flags/goals): Discover how to define goals for your feature flag experiments to measure their success.
- [Experiments](../feature-flags/testing-with-flags/experiments): Learn how to set up and run experiments using feature flags to test hypotheses and gather insights.
- [Experiments results](../feature-flags/testing-with-flags/experiment-results): Explore best practices and techniques for effectively utilizing experiments in your development process.
The [Audit logs](/feature-flags/audit-logs) presents how you can inspect the modifications and changes performed in your system. Use this feature to inspect and track the source of problems in your system.
2 changes: 1 addition & 1 deletion docs/integration/index.mdx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: Overview
title: Tools
sidebar_position: 1
slug: /integration
---
Expand Down
62 changes: 40 additions & 22 deletions sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,12 @@ const sidebars = {
{
type: 'category',
label: "Quickstart",
link: {
type: 'doc',
id: 'getting-started/quickstart/index',
},
className: 'sidebar-quickstart',
items: [
'getting-started/quickstart/index',
'getting-started/quickstart/create-an-api-key',
'getting-started/quickstart/create-your-first-flag',
'getting-started/quickstart/integrate-bucketeer'
Expand Down Expand Up @@ -105,6 +108,7 @@ const sidebars = {
'feature-flags/creating-feature-flags/targeting',
'feature-flags/creating-feature-flags/manage-variations',
'feature-flags/creating-feature-flags/auto-operation',
'feature-flags/creating-feature-flags/trigger',
'feature-flags/creating-feature-flags/evaluate-results',
'feature-flags/creating-feature-flags/settings-and-history'
],
Expand All @@ -115,15 +119,29 @@ const sidebars = {
label: 'API Keys',
className: 'sidebar-api-keys',
},
{
type: 'doc',
id: 'feature-flags/audit-logs',
label: 'Audit Logs',
},

{
type: 'html',
value: "<span class='sidebar-title'>Experimentation</span>",
defaultStyle: true,
},
{
type: 'category',
label: 'Testing With Flags',
className: 'sidebar-testing-with-flags',
link: {
type: 'doc',
id: 'experimentation/index',
},
items: [
'feature-flags/testing-with-flags/index',
'feature-flags/testing-with-flags/goals',
'feature-flags/testing-with-flags/experiments',
'feature-flags/testing-with-flags/using-experiments',
'experimentation/goals',
'experimentation/experiments',
'experimentation/using-experiments',
],
},
// {
Expand Down Expand Up @@ -169,23 +187,20 @@ const sidebars = {
defaultStyle: true,
},
{
type: 'doc',
id: 'integration/index',
label: 'Overview',
className: 'sidebar-overview',
},
{
type: 'doc',
id: 'integration/pushes',
label: 'Pushes',
className: 'sidebar-fcm',
},
{
type: 'doc',
id: 'integration/notifications',
label: 'Notifications',
className: 'sidebar-slack',
type: 'category',
label: 'Tools',
link: {
type: 'doc',
id: 'integration/index',
},
className: 'sidebar-overview',
items: [
'integration/pushes',
'integration/notifications',
],
},


{
type: 'html',
value: "<span class='sidebar-title'>Best practices</span>",
Expand All @@ -211,9 +226,12 @@ const sidebars = {
{
type: 'category',
label: 'Documentation Style',
link: {
type: 'doc',
id: 'contribution-guide/documentation-style/index',
},
className: 'sidebar-documentation-style-guide',
items: [
'contribution-guide/documentation-style/index',
'contribution-guide/documentation-style/consistency',
'contribution-guide/documentation-style/voice-and-tone',
'contribution-guide/documentation-style/formatting-and-organization',
Expand Down
58 changes: 58 additions & 0 deletions src/components/glossary/Glossary.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import React, { useState, useRef, useEffect } from 'react';
import style from './style.css'

export default function Glossary({word, content}) {
const [isHovered, setIsHovered] = useState(false);
const [hoveredWord, setHoveredWord] = useState('');
const [boxPosition, setBoxPosition] = useState({ top: 0, left: 0 });
const wordRef = useRef(null);

const handleMouseEnter = (word, event) => {
const wordRect = wordRef.current.getBoundingClientRect();
setHoveredWord(word);
/*setBoxPosition({
top: event.clientY, // Adjust the values as needed
left: event.clientX, // Adjust the values as needed
});*/
setBoxPosition({
top: wordRect.top - 45, // Adjust the values as needed
left: wordRect.left - 240, // Adjust the values as needed
});
setIsHovered(true);
};

const handleMouseLeave = () => {
setIsHovered(false);
};

return (
<span>
<span
onMouseEnter={(e) => handleMouseEnter('hoveredWord', e)}
onMouseLeave={handleMouseLeave}
style={{ textDecoration: 'underline', cursor: 'pointer' }}
ref={wordRef}
>
Word
</span>{' '}


{isHovered && (
<div
style={{
position: 'absolute',
background: 'white',
border: '1px solid #ccc',
width: '200px', // Adjust the width as needed
padding: '10px',
top: boxPosition.top,
left: boxPosition.left,
zIndex: 999,
}}
>
<p>{content}</p>
</div>
)}
</span>
);
};
47 changes: 47 additions & 0 deletions src/components/glossary/Glossary.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React, { useState, useRef, useEffect } from 'react';
import style from './style.css'

export default function Glossary({ word, content }) {
const [isPopupVisible, setPopupVisible] = useState(false);
const [spaceAtLeft, setSpaceAtLeft] = useState(0);
const wordRef = useRef(null);

const getScreenPosition = () => {
const wordRect = wordRef.current.getBoundingClientRect();
return {
left: wordRect.left,
}
}

const handleHover = () => {
setPopupVisible(true);
const { left } = getScreenPosition();
setSpaceAtLeft(left - 30);
}

return (
<span className="glossary" ref={wordRef}>
<span
className="glossary-word"
onMouseEnter={handleHover}
onMouseLeave={() => setPopupVisible(false)}
>
{word}
</span>
{isPopupVisible && (
<div
// onMouseLeave={() => setPopupVisible(false)}
// onMouseEnter={() => setPopupVisible(true)}
onClick={() => window.location='how-visual-kpi-works'}
className="popup top-arrow"
style={{
// top: `${spaceAtTop}px`,
left: `${spaceAtLeft}px`,
}}
>
{content}
</div>
)}
</span>
);
}
34 changes: 34 additions & 0 deletions src/components/glossary/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
.glossary {
cursor: help;
transition: transform 250ms;
transition-delay: 300ms;
}

.glossary .glossary-word {
font-weight: 500;
transition: color var(--ifm-transition-fast)
var(--ifm-transition-timing-default);
color: var(--ifm-link-hover-color);
text-decoration: var(--ifm-link-hover-decoration);
}

.glossary .popup {
display: block;
position: absolute;
left: 0;
/*width: 350px;*/
/*display: flex;
align-items: center;
justify-content: center;*/
border: 1px solid #573792;
background: #ffffff;
border-radius: 7px;
padding: 0.5rem;
/*box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);*/
/*z-index: 999;
margin-top: 0.8rem;*/
}

.glossary:hover .popup {
transform: translateY(0);
}
Loading
Loading