- name: Validate Loki Log Errors (Health Gate)
env:
\# Use your direct Loki URL or Grafana Loki proxy endpoint
LOKI_URL: "https://grafana.example.com/api/datasources/proxy/uid/loki"
GRAFANA_TOKEN: ${{ secrets.GRAFANA_SERVICE_ACCOUNT_TOKEN }}
SERVICE_NAME: "ton-connect"
DEPLOY_ENV: "production"
MAX_ALLOWED_ERRORS: "0" # Zero-tolerance threshold for errors in 5m window
run: |
echo "Scanning Loki logs for errors in service: ${SERVICE_NAME}..."
\# LogQL query: Count log lines containing 'error', 'exception', or 'fatal' over the last 5m
LOGQL_QUERY="sum(count_over_time({service=\\"${SERVICE_NAME}\\", environment=\\"${DEPLOY_ENV}\\"} |\~ \\"(?i)error|exception|fatal\\" \[5m\])) or vector(0)"
\# Query Loki Instant Query API
RESPONSE=$(curl -sG "${LOKI_URL}/loki/api/v1/query" \\
-H "Authorization: Bearer ${GRAFANA_TOKEN}" \\
--data-urlencode "query=${LOGQL_QUERY}")
\# Check API response status
STATUS=$(echo "${RESPONSE}" | jq -r '.status // "error"')
if \[ "${STATUS}" != "success" \]; then
echo "::error::Failed to query Loki API. Response: ${RESPONSE}"
exit 1
fi
\# Extract error line count from vector result
ERROR_COUNT=$(echo "${RESPONSE}" | jq -r '.data.result\[0\].value\[1\] // "0"')
echo "Found ${ERROR_COUNT} error log entries in the last 5 minutes."
\# Evaluate threshold
if \[ "${ERROR_COUNT}" -gt "${MAX_ALLOWED_ERRORS}" \]; then
echo "::error::Loki log check failed! ${ERROR_COUNT} error log entries found (Threshold: ${MAX_ALLOWED_ERRORS})."
\# Print sample matching error lines for faster debugging
SAMPLE_LOGS_QUERY="{service=\\"${SERVICE_NAME}\\", environment=\\"${DEPLOY_ENV}\\"} |\~ \\"(?i)error|exception|fatal\\""
echo "--- Recent Log Error Samples ---"
curl -sG "${LOKI_URL}/loki/api/v1/query_range" \\
-H "Authorization: Bearer ${GRAFANA_TOKEN}" \\
--data-urlencode "query=${SAMPLE_LOGS_QUERY}" \\
--data-urlencode "limit=5" | jq -r '.data.result\[\].values\[\]\[1\]'
echo "--------------------------------"
exit 1
fi
ech
o “Loki log verification passed successfully.”