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

Start to add eventing dashboards. #20

Merged
merged 1 commit into from
Dec 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/documentation.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ jobs:
- networking
- dashboard/service
- dashboard/job
- dashboard/cloudevent-receiver

steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
Expand Down
8 changes: 7 additions & 1 deletion cloudevent-broker/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,20 @@ No requirements.

| Name | Source | Version |
|------|--------|---------|
| <a name="module_ingress-dashboard"></a> [ingress-dashboard](#module\_ingress-dashboard) | ../dashboard/service | n/a |
| <a name="module_http"></a> [http](#module\_http) | ../dashboard/sections/http | n/a |
| <a name="module_layout"></a> [layout](#module\_layout) | ../dashboard/sections/layout | n/a |
| <a name="module_logs"></a> [logs](#module\_logs) | ../dashboard/sections/logs | n/a |
| <a name="module_resources"></a> [resources](#module\_resources) | ../dashboard/sections/resources | n/a |
| <a name="module_topic"></a> [topic](#module\_topic) | ../dashboard/sections/topic | n/a |
| <a name="module_width"></a> [width](#module\_width) | ../dashboard/sections/width | n/a |

## Resources

| Name | Type |
|------|------|
| [cosign_sign.this](https://registry.terraform.io/providers/chainguard-dev/cosign/latest/docs/resources/sign) | resource |
| [google_cloud_run_v2_service.this](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/cloud_run_v2_service) | resource |
| [google_monitoring_dashboard.dashboard](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/monitoring_dashboard) | resource |
| [google_pubsub_topic.this](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/pubsub_topic) | resource |
| [google_pubsub_topic_iam_binding.ingress-publishes-events](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/pubsub_topic_iam_binding) | resource |
| [google_service_account.this](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/service_account) | resource |
Expand Down
54 changes: 51 additions & 3 deletions cloudevent-broker/ingress.tf
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,55 @@ resource "google_cloud_run_v2_service" "this" {
}
}

module "ingress-dashboard" {
source = "../dashboard/service"
service_name = var.name
module "topic" {
source = "../dashboard/sections/topic"
title = "Broker Events"
topic_prefix = var.name
}

module "logs" {
source = "../dashboard/sections/logs"
title = "Service Logs"
filter = ["resource.type=\"cloud_run_revision\""]
}

module "http" {
source = "../dashboard/sections/http"
title = "HTTP"
filter = ["resource.type=\"cloud_run_revision\""]
}

module "resources" {
source = "../dashboard/sections/resources"
title = "Resources"
filter = ["resource.type=\"cloud_run_revision\""]
}

module "width" { source = "../dashboard/sections/width" }

module "layout" {
source = "../dashboard/sections/layout"
sections = [
module.topic.section,
module.logs.section,
module.http.section,
module.resources.section,
]
}

resource "google_monitoring_dashboard" "dashboard" {
dashboard_json = jsonencode({
displayName = "Cloud Events Broker Ingress: ${var.name}"
dashboardFilters = [{
filterType = "RESOURCE_LABEL"
stringValue = var.name
labelKey = "service_name"
}]

// https://cloud.google.com/monitoring/api/ref_v3/rest/v1/projects.dashboards#mosaiclayout
mosaicLayout = {
columns = module.width.size
tiles = module.layout.tiles,
}
})
}
2 changes: 1 addition & 1 deletion cloudevent-recorder/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ No requirements.

| Name | Source | Version |
|------|--------|---------|
| <a name="module_recorder-dashboard"></a> [recorder-dashboard](#module\_recorder-dashboard) | ../dashboard/service | n/a |
| <a name="module_recorder-dashboard"></a> [recorder-dashboard](#module\_recorder-dashboard) | ../dashboard/cloudevent-receiver | n/a |
| <a name="module_triggers"></a> [triggers](#module\_triggers) | ../cloudevent-trigger | n/a |

## Resources
Expand Down
10 changes: 7 additions & 3 deletions cloudevent-recorder/recorder.tf
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ resource "google_cloud_run_v2_service" "recorder-service" {
}

resource "random_id" "trigger-suffix" {
for_each = local.regional-types
for_each = var.types
byte_length = 2
}

Expand All @@ -109,7 +109,7 @@ module "triggers" {

source = "../cloudevent-trigger"

name = "${var.name}-${random_id.trigger-suffix[each.key].hex}"
name = "${var.name}-${random_id.trigger-suffix[each.value.type].hex}"
project_id = var.project_id
broker = var.broker[each.value.region]
filter = { "type" : each.value.type }
Expand All @@ -122,6 +122,10 @@ module "triggers" {
}

module "recorder-dashboard" {
source = "../dashboard/service"
source = "../dashboard/cloudevent-receiver"
service_name = var.name

triggers = {
for type in var.types : "type: ${each.key}" => "${var.name}-${random_id.trigger-suffix[each.value.type].hex}"
}
}
1 change: 1 addition & 0 deletions dashboard/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
The modules in this directory define [`google_monitoring_dashboard`](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/monitoring_dashboard) resources in a repeatable structured way.

- The [Service](service/README.md) and [Job](job/README.md) modules define pre-configured dashboards for Cloud Run services and Cloud Run jobs, respectively.
- The [`cloudevent-receiver`](cloudevent-receiver/README.md) module defines a pre-configured dashboard for a Cloud Run-based event handler receiving events from a `cloudevent-trigger`.
- The modules in [`./widgets`](widgets/) define the widgets used by the dashboards, in a way that can be reused to create custom dashboards.
99 changes: 99 additions & 0 deletions dashboard/cloudevent-receiver/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# `dashboard/cloudevent-receiver`

This module provisions a Google Cloud Monitoring dashboard for a regionalized Cloud Run service that receives Cloud Events from one or more `cloudevent-trigger`.

It assumes the service has the same name in all regions.

```hcl
// Create a network with several regional subnets
module "networking" {
source = "chainguard-dev/glue/cloudrun//networking"

name = "my-networking"
project_id = var.project_id
regions = [...]
}

// Run a regionalized cloud run service "receiver" to handle events.
resource "google_cloud_run_v2_service" "receiver" {
for_each = module.networking.regional-networks
name = "receiver"

//...
template {
//...
containers {
image = "..."
}
}
}

module "cloudevent-trigger" {
for_each = module.networking.regional-networks

source = "chainguard-dev/glue/cloudrun//cloudevent-trigger"

name = "my-trigger"
project_id = var.project_id
broker = module.cloudevent-broker.broker[each.key]
filter = { "type" : "dev.chainguard.foo" }

depends_on = [google_cloud_run_v2_service.sockeye]
private-service = {
region = each.key
name = google_cloud_run_v2_service.receiver[each.key].name
}
}

// Set up a dashboard for a regionalized event handler named "receiver".
module "receiver-dashboard" {
source = "chainguard-dev/glue/cloudrun//dashboard/cloudevent-receiver"
service_name = "receiver"

triggers = {
"type dev.chainguard.foo": "my-trigger"
}
}
```

The dashboard it creates includes widgets for service logs, request count, latency (p50,p95,p99), instance count grouped by revision, CPU and memory utilization, startup latency, and sent/received bytes.

<!-- BEGIN_TF_DOCS -->
## Requirements

No requirements.

## Providers

| Name | Version |
|------|---------|
| <a name="provider_google"></a> [google](#provider\_google) | n/a |

## Modules

| Name | Source | Version |
|------|--------|---------|
| <a name="module_http"></a> [http](#module\_http) | ../sections/http | n/a |
| <a name="module_layout"></a> [layout](#module\_layout) | ../sections/layout | n/a |
| <a name="module_logs"></a> [logs](#module\_logs) | ../sections/logs | n/a |
| <a name="module_resources"></a> [resources](#module\_resources) | ../sections/resources | n/a |
| <a name="module_subscription"></a> [subscription](#module\_subscription) | ../sections/subscription | n/a |
| <a name="module_width"></a> [width](#module\_width) | ../sections/width | n/a |

## Resources

| Name | Type |
|------|------|
| [google_monitoring_dashboard.dashboard](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/monitoring_dashboard) | resource |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_service_name"></a> [service\_name](#input\_service\_name) | Name of the service(s) to monitor | `string` | n/a | yes |
| <a name="input_triggers"></a> [triggers](#input\_triggers) | A mapping from a descriptive name to a subscription name prefix. | `map(string)` | n/a | yes |

## Outputs

No outputs.
<!-- END_TF_DOCS -->
57 changes: 57 additions & 0 deletions dashboard/cloudevent-receiver/dashboard.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
module "subscription" {
for_each = var.triggers

source = "../sections/subscription"
title = "Events ${each.key}"

subscription_prefix = each.value
}

module "logs" {
source = "../sections/logs"
title = "Service Logs"
filter = ["resource.type=\"cloud_run_revision\""]
}

module "http" {
source = "../sections/http"
title = "HTTP"
filter = ["resource.type=\"cloud_run_revision\""]
}

module "resources" {
source = "../sections/resources"
title = "Resources"
filter = ["resource.type=\"cloud_run_revision\""]
}

module "width" { source = "../sections/width" }

module "layout" {
source = "../sections/layout"
sections = concat([
for key in sort(keys(var.triggers)) : module.subscription[key].section
],
[
module.logs.section,
module.http.section,
module.resources.section,
])
}

resource "google_monitoring_dashboard" "dashboard" {
dashboard_json = jsonencode({
displayName = "Cloud Event Receiver: ${var.service_name}"
dashboardFilters = [{
filterType = "RESOURCE_LABEL"
stringValue = var.service_name
labelKey = "service_name"
}]

// https://cloud.google.com/monitoring/api/ref_v3/rest/v1/projects.dashboards#mosaiclayout
mosaicLayout = {
columns = module.width.size
tiles = module.layout.tiles,
}
})
}
9 changes: 9 additions & 0 deletions dashboard/cloudevent-receiver/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
variable "service_name" {
description = "Name of the service(s) to monitor"
type = string
}

variable "triggers" {
description = "A mapping from a descriptive name to a subscription name prefix."
type = map(string)
}
88 changes: 88 additions & 0 deletions dashboard/sections/subscription/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
variable "title" { type = string }
variable "subscription_prefix" { type = string }
variable "collapsed" { default = false }

module "width" { source = "../width" }

module "received-events" {
source = "../../widgets/xy"
title = "Events Pushed"
filter = [
"resource.type=\"pubsub_subscription\"",
"metric.type=\"pubsub.googleapis.com/subscription/push_request_count\"",
"resource.label.\"subscription_id\"=monitoring.regex.full_match(\"${var.subscription_prefix}-.*\")",
]
group_by_fields = [
"resource.label.\"subscription_id\"",
"metric.label.\"response_class\""
]
primary_align = "ALIGN_MEAN"
primary_reduce = "REDUCE_NONE"
}

module "push-latency" {
source = "../../widgets/latency"
title = "Push latency"
filter = [
"resource.type=\"pubsub_subscription\"",
"metric.type=\"pubsub.googleapis.com/subscription/push_request_latencies\"",
"resource.label.\"subscription_id\"=monitoring.regex.full_match(\"${var.subscription_prefix}-.*\")",
]
group_by_fields = ["resource.label.\"subscription_id\""]
}

module "oldest-unacked" {
source = "../../widgets/xy"
title = "Oldest unacked message age"
filter = [
"resource.type=\"pubsub_subscription\"",
"metric.type=\"pubsub.googleapis.com/subscription/oldest_unacked_message_age\"",
"resource.label.\"subscription_id\"=monitoring.regex.full_match(\"${var.subscription_prefix}-.*\")",
]
group_by_fields = ["resource.label.\"subscription_id\""]
primary_align = "ALIGN_MAX"
primary_reduce = "REDUCE_NONE"
}

locals {
columns = 3
unit = module.width.size / local.columns

// https://www.terraform.io/language/functions/range
// N columns, unit width each ([0, unit, 2 * unit, ...])
col = range(0, local.columns * local.unit, local.unit)

tiles = [{
yPos = 0,
xPos = local.col[0],
height = local.unit,
width = local.unit,
widget = module.received-events.widget,
},
{
yPos = 0,
xPos = local.col[1],
height = local.unit,
width = local.unit,
widget = module.push-latency.widget,
},
{
yPos = 0,
xPos = local.col[2],
height = local.unit,
width = local.unit,
widget = module.oldest-unacked.widget,
}]
}

module "collapsible" {
source = "../collapsible"

title = var.title
tiles = local.tiles
collapsed = var.collapsed
}

output "section" {
value = module.collapsible.section
}
Loading
Loading