# Go SDK

Use the `cronitor-go` module to report job runs, heartbeats, and metrics to Cronitor from Go 1.21 or later.

## Install

```bash
go get github.com/cronitorio/cronitor-go
```

## Configure

Set the `CRONITOR_API_KEY` environment variable to your SDK Integration key. Copy the key from Settings → API Keys at https://cronitor.io/app/settings/api. Keep the key in the environment or a secret store of the runtime. Do not commit it.

The package reads `CRONITOR_API_KEY` when it initializes, so you do not need configuration code.

## Monitor a job

Wrap the main function of the job with `cronitor.Job`:

```go
package main

import (
	"log"

	"github.com/cronitorio/cronitor-go"
)

func main() {
	_, err := cronitor.Job("send-invoices", func() (any, error) {
		return nil, sendInvoices()
	})
	if err != nil {
		log.Fatal(err)
	}
}
```

- Before the function starts, the SDK sends a `run` event.
- When the function returns a nil error, the SDK sends a `complete` event with the elapsed time as the `duration` metric.
- When the function returns an error or panics, the SDK sends a `fail` event with the error text and the `duration` metric. `cronitor.Job` gives back the error, or panics again.
- The events go to the monitor with the key `send-invoices`. If no monitor has this key, Cronitor creates one on the first event.

The SDK sends the return value of the function as the message of the `complete` event. To not send it, add `cronitor.WithLogOutput(false)` as the last argument of `cronitor.Job`.

To send the events yourself, use a monitor:

```go
monitor := cronitor.NewMonitor("send-invoices")
monitor.Ping(cronitor.PingOptions{State: cronitor.StateRun})
monitor.Ping(cronitor.PingOptions{State: cronitor.StateComplete}) // or cronitor.StateFail
```

## Send a heartbeat

Send a ping each time the process completes a unit of useful work:

```go
monitor := cronitor.NewMonitor("queue-worker")
if err := monitor.Ping(cronitor.PingOptions{Message: "Alive!"}); err != nil {
	log.Printf("cronitor ping: %v", err)
}
```

To attach metrics, set `Metrics`. The SDK sends each item as `metric=name:value`:

```go
monitor.Ping(cronitor.PingOptions{
	Metrics: map[string]float64{"count": 100, "error_count": 3},
})
```

If you only want to record custom metrics, use a heartbeat monitor. See [Custom Metrics](https://cronitor.io/docs/custom-metrics.md).

## Verify

After one real run, check the state of the monitor. A successful telemetry response shows only that Cronitor received the request. It does not show that Cronitor stored the event or matched it to a monitor.

With the [MCP server](https://cronitor.io/docs/mcp-server.md):

```text
get_status({"key": "send-invoices"})
```

With [CronitorCLI](https://cronitor.io/docs/using-cronitor-cli.md):

```bash
cronitor status send-invoices
```

If `CRONITOR_API_KEY` is not set, the SDK logs an error and sends no events. `Ping` then returns `nil`, and the job still runs.

## Reference

- [cronitor-go on GitHub](https://github.com/cronitorio/cronitor-go): the full README, including monitor attributes and YAML configuration.
- [Telemetry API](https://cronitor.io/docs/telemetry-api.md): the events and parameters that the SDK sends.
