Use Settings to configure delivery, Routing to select events, Logs to inspect delivery history, and Help for this guide. Routing requires Tier 1; Tier 2 adds request rules. Log visibility, payload previews, and deletion can be delegated separately with Tier 2 role permissions.
Send signals to Grafana Loki for structured log lines.
Grafana Loki is a premium SignalPress service. The active license must include service_loki or *.
Hub service ID: loki. Index: Integrations Overview. Target from PHP: Service Targeting.
Get the push credentials
Grafana Cloud
Grafana’s Connections menu (Data sources, Integrations, and so on) does not give you a Loki write token. Follow this order: create a write access policy, create a token on that policy, then copy the Loki URL and user ID from the Cloud Portal.
1. Create a Cloud access policy with logs:write
- Open your Grafana Cloud stack (for example
https://yourstack.grafana.net). - Open Administration (gear icon, bottom of the left nav).
- Go to Users and access → Cloud access policies.
- Click Create access policy.
- Name it something clear, for example
signalpress-loki-write. - Scope it to this stack.
- Under scopes / permissions, enable Logs → Write (
logs:write). - Create the policy.
Do not reuse a policy whose name ends in -read or whose scopes are only logs:read, metrics:read, and similar. A token created on a read-only policy returns authentication error: invalid scope requested when SignalPress pushes logs.
Do not use Administration → Service accounts for this. Service-account tokens are for the Grafana UI/API and usually lack Loki write scopes.
2. Create a token on that write policy
- Open the access policy you just created (
signalpress-loki-write). - Click Add token / Create token.
- Give the token a name (for example
signalpress). - Confirm the predefined scopes include
logs:writebefore you create it. - Create the token and copy it immediately — Grafana only shows it once.
- Paste it into SignalPress as API Token / Password, then click Save changes.
3. Copy the Loki URL and user ID from the Cloud Portal
- In Grafana, open the Cloud portal link (often on the Get started / home page under Cloud organization), or go to [grafana.com](https://grafana.com/) and open the portal for your account.
- On your stack tile, click Details.
- On the Loki / Grafana Cloud Logs tile, click Details.
- Copy:
- URL → SignalPress Push URL
Example: https://logs-prod-xxx.grafana.net
Do not use your Grafana app URL (https://yourstack.grafana.net).
- User / User ID (numeric) → SignalPress Username / User ID
This is not your email address.
- Leave SignalPress Tenant ID blank for Grafana Cloud.
- Set a Project name, save again, enable the service if needed, and save once more.
- Click Send test signal. A successful push commonly returns HTTP
204.
SignalPress appends /loki/api/v1/push when the Push URL does not already include that path.
Settings fields
| Field | Purpose |
|---|---|
| Push URL | Loki distributor or full push path. |
| Username / User ID | Basic auth user (Grafana Cloud numeric user ID). |
| API Token / Password | Write token or basic-auth password. |
| Tenant ID | X-Scope-OrgID for multi-tenant/self-hosted setups. Leave blank for Grafana Cloud. |
| Job Label | Loki stream label job. Default: signalpress. |
| Default Level | Used when an event omits level or sends an invalid level. Default: info. |
The signalpress/loki/payload filter can adjust the log line JSON before push.
Optional: Connections → Data sources → Loki can show the same URL and user for reading logs, but the write token must still come from a Cloud access policy with logs:write.
Self-hosted Loki
- Use your distributor base URL or the full push path, for example
http://loki:3100orhttps://loki.example.com/loki/api/v1/push. - If a reverse proxy requires basic auth, fill Username and API Token / Password.
- If Loki runs in multi-tenant mode, set Tenant ID to the org/tenant string your proxy expects (
X-Scope-OrgID). - Save and send a test signal.
- [Loki HTTP API — push](https://grafana.com/docs/loki/latest/reference/loki-http-api/#ingest-logs)
- [Grafana Cloud access policies](https://grafana.com/docs/grafana-cloud/security-and-account-management/authentication-and-permissions/access-policies/)
Test the connection
- In SignalPress, click Send test signal and confirm it succeeds.
- In Grafana, open Explore (compass icon).
- Select your Loki data source (often named like
grafanacloud-yourstack-logs). - Switch the query editor to Code (not Builder, and not Go queryless).
- Set the time range (top right) to Last 15 minutes.
- Paste this query and click Run query:
Text
{job="signalpress"}
- Confirm a JSON log line that includes
"event":"signalpress_test".
If you changed Job Label in SignalPress Settings, use that value instead of signalpress.
If the default query is empty, try:
Text
{job=~".+"} |= "signalpress_test"
or:
Text
{source="connection-test"}
A successful SignalPress test means Loki accepted the push. Explore only shows the line when the data source, time range, and label selector match.
Send a signal
PHP
sp_capture( 'payment_provider_failed', [ 'message' => 'The payment provider returned an unexpected response.', 'level' => 'error', 'order_id' => 123, 'response' => $provider_response, ], [ 'source' => 'checkout', 'services' => [ 'loki' ], ] );
Supported levels are debug, info, warning, error, and critical. Level is also stored as a Loki stream label. An invalid or omitted level uses the service default.
Each push sends a JSON log line with message, level, event, project, environment, source, hostname, nested payload and context, site URL, and SignalPress version. Stream labels stay low-cardinality: job, level, environment, project, source, and hostname.
Troubleshooting
- A disabled test button means Push URL or Project has not been saved.
invalid scope requestedmeans the token’s access policy lackslogs:write. Create a new write policy (step 1 above); do not add a token to a-readpolicy.- HTTP
401or403on Grafana Cloud usually means one of: - Push URL is the Grafana app host (
yourstack.grafana.net) instead of the Loki host (logs-prod-....grafana.net) - Username is missing or is an email instead of the numeric Loki User ID
- Token is from a service account or a read-only policy
- Tenant ID was filled in (must be blank for Cloud)
- Settings were not saved before testing
- HTTP
400often means invalid JSON, bad timestamps, or label values Loki rejected. - Successful ingestion returns a
2xxresponse (commonly204 No Content). - Test succeeds but Explore is empty: use Code mode, Last 15 minutes, data source
...-logs, and{job="signalpress"}(or your custom job label).
What to read next
- Integrations Overview — browse and activate services
- Your First Connection Test — send a test signal and read the log
- Advanced Event Routing — per-service event filters
- Connection Tests and Delivery Log — interpret delivery results
- Service Targeting — limit destinations from PHP