Setting SLOs on HTTP Paths and RPC Methods
You can set SLOs on HTTP Paths or RPC Methods that represent key endpoints for your application (for example, revenue-critical URIs or core RPC methods).
Enabling SLOs on these entities configures SLO tracking for both Request Duration and Request Error Rate. When a root cause impacts one of these endpoints and drives its SLO at risk or into violation, Causely treats that root cause as Urgent.
The recommended way to manage these SLOs is to use Entity Configs of type EntityTier.
Prerequisite
Each example below reuses the helper utilities defined in the Authentication and GraphQL Clients sections (get_causely_access_token, create_graphql_client, post_query, and their language equivalents).
Enable SLOs on an HTTP Path or RPC Method
- python
- javascript
- bash
- go
- graphql
import os
import json
# Reuse helpers defined earlier in this guide:
# - get_causely_access_token
# - create_graphql_client
# - post_query
CREATE_CONFIGS_MUTATION = """
mutation CreateEntityConfigs($entityConfigs: [EntityConfigInput!]!) {
createEntityConfigs(entityConfigs: $entityConfigs) {
entityId
type
data
}
}
"""
if __name__ == "__main__":
cid, secret = os.getenv("CAUSELY_CLIENT_ID"), os.getenv("CAUSELY_CLIENT_SECRET")
if not cid or not secret:
raise EnvironmentError("Missing CAUSELY_CLIENT_ID or CAUSELY_CLIENT_SECRET")
token = get_causely_access_token(cid, secret)
client = create_graphql_client(token)
# Replace with the entityId of the HTTP Path or RPC Method you want to enable SLOs on
entity_id = "7c4bba4c-1942-5fc4-87e2-d1f2c483d2c2"
variables = {
"entityConfigs": [{
"type": "EntityTier",
"entityId": entity_id,
"data": "sloEnabled",
}]
}
result = post_query(client, CREATE_CONFIGS_MUTATION, variables)
print(json.dumps(result, indent=2))
// Reuses helpers defined earlier in this guide:
// - getCauselyAccessToken
// - createGraphQLClient
// - postQuery (for queries/mutations)
const { gql } = require('@apollo/client');
const { CAUSELY_CLIENT_ID, CAUSELY_CLIENT_SECRET } = process.env;
const CREATE_CONFIGS_MUTATION = `
mutation CreateEntityConfigs($entityConfigs: [EntityConfigInput!]!) {
createEntityConfigs(entityConfigs: $entityConfigs) {
entityId
type
data
}
}
`;
(async () => {
if (!CAUSELY_CLIENT_ID || !CAUSELY_CLIENT_SECRET) {
console.error('Missing CAUSELY_CLIENT_ID or CAUSELY_CLIENT_SECRET');
process.exit(1);
}
const token = await getCauselyAccessToken(CAUSELY_CLIENT_ID, CAUSELY_CLIENT_SECRET);
const client = createGraphQLClient(token);
// Replace with the entityId of the HTTP Path or RPC Method you want to enable SLOs on
const entityId = '7c4bba4c-1942-5fc4-87e2-d1f2c483d2c2';
const variables = {
entityConfigs: [
{
type: 'EntityTier',
entityId,
data: 'sloEnabled',
},
],
};
const result = await client.mutate({
mutation: gql(CREATE_CONFIGS_MUTATION),
variables,
});
console.log(JSON.stringify(result.data, null, 2));
})();
#!/usr/bin/env bash
set -euo pipefail
# Prerequisites:
# - CAUSELY_CLIENT_ID / CAUSELY_CLIENT_SECRET exported
# - CAUSELY_ACCESS_TOKEN exported (see Authentication section)
# - post_query / post_query_curl functions defined (see Bash GraphQL helpers section)
# - jq installed
# Replace with the entityId of the HTTP Path or RPC Method you want to enable SLOs on
ENTITY_ID="7c4bba4c-1942-5fc4-87e2-d1f2c483d2c2"
cat > create_entity_configs.graphql << 'EOF'
mutation CreateEntityConfigs($entityConfigs: [EntityConfigInput!]!) {
createEntityConfigs(entityConfigs: $entityConfigs) {
entityId
type
data
}
}
EOF
cat > create_entity_configs_variables.json << EOF
{
"entityConfigs": [
{
"type": "EntityTier",
"entityId": "${ENTITY_ID}",
"data": "sloEnabled"
}
]
}
EOF
QUERY=$(tr '\n' ' ' < create_entity_configs.graphql)
VARIABLES=$(cat create_entity_configs_variables.json)
post_query_curl "$QUERY" "$VARIABLES"
rm -f create_entity_configs.graphql create_entity_configs_variables.json
package main
import (
"encoding/json"
"fmt"
"os"
)
// Reuse helpers defined earlier:
// - getToken(id, secret, url)
// - createGraphQLClient(accessToken string) *graphql.Client
// - postQuery(client *graphql.Client, queryString string, variables map[string]interface{}) (interface{}, error)
const createConfigsMutation = `
mutation CreateEntityConfigs($entityConfigs: [EntityConfigInput!]!) {
createEntityConfigs(entityConfigs: $entityConfigs) {
entityId
type
data
}
}
`
func main() {
id, secret := os.Getenv("CAUSELY_CLIENT_ID"), os.Getenv("CAUSELY_CLIENT_SECRET")
if id == "" || secret == "" {
fmt.Fprintln(os.Stderr, "Missing CAUSELY_CLIENT_ID or CAUSELY_CLIENT_SECRET")
os.Exit(1)
}
token, err := getToken(id, secret, "https://auth.causely.app/frontegg/identity/resources/auth/v2/api-token")
if err != nil {
fmt.Fprintln(os.Stderr, "Error getting token:", err)
os.Exit(1)
}
client := createGraphQLClient(token)
// Replace with the entityId of the HTTP Path or RPC Method you want to enable SLOs on
entityID := "7c4bba4c-1942-5fc4-87e2-d1f2c483d2c2"
variables := map[string]interface{}{
"entityConfigs": []map[string]interface{}{
{
"type": "EntityTier",
"entityId": entityID,
"data": "sloEnabled",
},
},
}
result, err := postQuery(client, createConfigsMutation, variables)
if err != nil {
fmt.Fprintln(os.Stderr, "Error enabling SLO:", err)
os.Exit(1)
}
out, _ := json.MarshalIndent(result, "", " ")
fmt.Println(string(out))
}
mutation CreateEntityConfigs($entityConfigs: [EntityConfigInput!]!) {
createEntityConfigs(entityConfigs: $entityConfigs) {
entityId
type
data
}
}
Variables (example):
{
"entityConfigs": [
{
"type": "EntityTier",
"entityId": "7c4bba4c-1942-5fc4-87e2-d1f2c483d2c2",
"data": "sloEnabled"
}
]
}
Check whether an HTTP Path or RPC Method has SLOs enabled
- python
- javascript
- bash
- go
- graphql
import os
import json
# Reuse helpers defined earlier:
# - get_causely_access_token
# - create_graphql_client
# - post_query
GET_CONFIGS_QUERY = """
query GetEntityConfigs($entityId: String!) {
entityConfigs(entityId: $entityId) {
type
data
entityId
}
}
"""
if __name__ == "__main__":
cid, secret = os.getenv("CAUSELY_CLIENT_ID"), os.getenv("CAUSELY_CLIENT_SECRET")
if not cid or not secret:
raise EnvironmentError("Missing CAUSELY_CLIENT_ID or CAUSELY_CLIENT_SECRET")
token = get_causely_access_token(cid, secret)
client = create_graphql_client(token)
entity_id = "2f3ce84a-18b8-5d4c-820d-5b747cbb7f13"
result = post_query(client, GET_CONFIGS_QUERY, {"entityId": entity_id})
print(json.dumps(result, indent=2))
const { gql } = require('@apollo/client');
const { CAUSELY_CLIENT_ID, CAUSELY_CLIENT_SECRET } = process.env;
const GET_CONFIGS_QUERY = `
query GetEntityConfigs($entityId: String!) {
entityConfigs(entityId: $entityId) {
type
data
entityId
}
}
`;
(async () => {
const token = await getCauselyAccessToken(CAUSELY_CLIENT_ID, CAUSELY_CLIENT_SECRET);
const client = createGraphQLClient(token);
const entityId = '2f3ce84a-18b8-5d4c-820d-5b747cbb7f13';
const result = await client.query({
query: gql(GET_CONFIGS_QUERY),
variables: { entityId },
fetchPolicy: 'no-cache',
});
console.log(JSON.stringify(result.data, null, 2));
})();
#!/usr/bin/env bash
set -euo pipefail
ENTITY_ID="2f3ce84a-18b8-5d4c-820d-5b747cbb7f13"
cat > get_entity_configs.graphql << 'EOF'
query GetEntityConfigs($entityId: String!) {
entityConfigs(entityId: $entityId) {
type
data
entityId
}
}
EOF
cat > get_entity_configs_variables.json << EOF
{ "entityId": "${ENTITY_ID}" }
EOF
QUERY=$(tr '\n' ' ' < get_entity_configs.graphql)
VARIABLES=$(cat get_entity_configs_variables.json)
post_query_curl "$QUERY" "$VARIABLES"
rm -f get_entity_configs.graphql get_entity_configs_variables.json
package main
import (
"encoding/json"
"fmt"
"os"
)
// Reuse helpers defined earlier:
// - getToken(id, secret, url)
// - createGraphQLClient(accessToken string) *graphql.Client
// - postQuery(client *graphql.Client, queryString string, variables map[string]interface{}) (interface{}, error)
const getConfigsQuery = `
query GetEntityConfigs($entityId: String!) {
entityConfigs(entityId: $entityId) {
type
data
entityId
}
}
`
func main() {
id, secret := os.Getenv("CAUSELY_CLIENT_ID"), os.Getenv("CAUSELY_CLIENT_SECRET")
if id == "" || secret == "" {
fmt.Fprintln(os.Stderr, "Missing CAUSELY_CLIENT_ID or CAUSELY_CLIENT_SECRET")
os.Exit(1)
}
token, err := getToken(id, secret, "https://auth.causely.app/frontegg/identity/resources/auth/v2/api-token")
if err != nil {
fmt.Fprintln(os.Stderr, "Error getting token:", err)
os.Exit(1)
}
client := createGraphQLClient(token)
// Replace with the entityId of the HTTP Path or RPC Method you want to inspect
entityID := "2f3ce84a-18b8-5d4c-820d-5b747cbb7f13"
variables := map[string]interface{}{
"entityId": entityID,
}
result, err := postQuery(client, getConfigsQuery, variables)
if err != nil {
fmt.Fprintln(os.Stderr, "Error querying configs:", err)
os.Exit(1)
}
out, _ := json.MarshalIndent(result, "", " ")
fmt.Println(string(out))
// Look for: type == "EntityTier" and data == "sloEnabled"
}
GetEntityConfigs($entityId: String!) {
entityConfigs(entityId: $entityId) {
type
data
entityId
}
}
Variables (example):
{
"entityId": "2f3ce84a-18b8-5d4c-820d-5b747cbb7f13"
}
Remove SLOs from an HTTP Path or RPC Method
- python
- javascript
- bash
- go
- graphql
import os
import json
# Reuse helpers defined earlier:
# - get_causely_access_token
# - create_graphql_client
# - post_query
DELETE_CONFIG_MUTATION = """
mutation DeleteEntityConfig($entityId: String!, $configType: String!) {
deleteEntityConfig(entityId: $entityId, configType: $configType)
}
"""
if __name__ == "__main__":
cid, secret = os.getenv("CAUSELY_CLIENT_ID"), os.getenv("CAUSELY_CLIENT_SECRET")
if not cid or not secret:
raise EnvironmentError("Missing CAUSELY_CLIENT_ID or CAUSELY_CLIENT_SECRET")
token = get_causely_access_token(cid, secret)
client = create_graphql_client(token)
entity_id = "2f3ce84a-18b8-5d4c-820d-5b747cbb7f13"
result = post_query(client, DELETE_CONFIG_MUTATION, {
"entityId": entity_id,
"configType": "EntityTier"
})
print(json.dumps(result, indent=2))
const { gql } = require('@apollo/client');
const { CAUSELY_CLIENT_ID, CAUSELY_CLIENT_SECRET } = process.env;
const DELETE_CONFIG_MUTATION = `
mutation DeleteEntityConfig($entityId: String!, $configType: String!) {
deleteEntityConfig(entityId: $entityId, configType: $configType)
}
`;
(async () => {
const token = await getCauselyAccessToken(CAUSELY_CLIENT_ID, CAUSELY_CLIENT_SECRET);
const client = createGraphQLClient(token);
const entityId = '2f3ce84a-18b8-5d4c-820d-5b747cbb7f13';
const result = await client.mutate({
mutation: gql(DELETE_CONFIG_MUTATION),
variables: { entityId, configType: 'EntityTier' },
});
console.log(JSON.stringify(result.data, null, 2));
})();
#!/usr/bin/env bash
set -euo pipefail
ENTITY_ID="2f3ce84a-18b8-5d4c-820d-5b747cbb7f13"
cat > delete_entity_config.graphql << 'EOF'
mutation DeleteEntityConfig($entityId: String!, $configType: String!) {
deleteEntityConfig(entityId: $entityId, configType: $configType)
}
EOF
cat > delete_entity_config_variables.json << EOF
{
"entityId": "${ENTITY_ID}",
"configType": "EntityTier"
}
EOF
QUERY=$(tr '\n' ' ' < delete_entity_config.graphql)
VARIABLES=$(cat delete_entity_config_variables.json)
post_query_curl "$QUERY" "$VARIABLES"
rm -f delete_entity_config.graphql delete_entity_config_variables.json
package main
import (
"encoding/json"
"fmt"
"os"
)
// Reuse helpers defined earlier:
// - getToken(id, secret, url)
// - createGraphQLClient(accessToken string) *graphql.Client
// - postQuery(client *graphql.Client, queryString string, variables map[string]interface{}) (interface{}, error)
const deleteConfigMutation = `
mutation DeleteEntityConfig($entityId: String!, $configType: String!) {
deleteEntityConfig(entityId: $entityId, configType: $configType)
}
`
func main() {
id, secret := os.Getenv("CAUSELY_CLIENT_ID"), os.Getenv("CAUSELY_CLIENT_SECRET")
if id == "" || secret == "" {
fmt.Fprintln(os.Stderr, "Missing CAUSELY_CLIENT_ID or CAUSELY_CLIENT_SECRET")
os.Exit(1)
}
token, err := getToken(id, secret, "https://auth.causely.app/frontegg/identity/resources/auth/v2/api-token")
if err != nil {
fmt.Fprintln(os.Stderr, "Error getting token:", err)
os.Exit(1)
}
client := createGraphQLClient(token)
// Replace with the entityId of the HTTP Path or RPC Method you want to remove SLOs from
entityID := "2f3ce84a-18b8-5d4c-820d-5b747cbb7f13"
variables := map[string]interface{}{
"entityId": entityID,
"configType": "EntityTier",
}
result, err := postQuery(client, deleteConfigMutation, variables)
if err != nil {
fmt.Fprintln(os.Stderr, "Error deleting config:", err)
os.Exit(1)
}
out, _ := json.MarshalIndent(result, "", " ")
fmt.Println(string(out))
}
mutation DeleteEntityConfig($entityId: String!, $configType: String!) {
deleteEntityConfig(entityId: $entityId, configType: $configType)
}
Variables (example):
{
"entityId": "2f3ce84a-18b8-5d4c-820d-5b747cbb7f13",
"configType": "EntityTier"
}