Fastly
Mit Fastlys Log-Streaming in Echtzeit können die Request-Logs Ihres Dienstes über HTTPS an Ahrefs gesendet werden. Sie fügen Ihrem Fastly-Dienst über das Fastly-Kontrollpanel einen Logging-Endpunkt hinzu; Ahrefs benötigt niemals Zugriff auf Ihr Fastly-Konto.
Voraussetzungen
- Ein Fastly-CDN-Dienst, der die Domain Ihres Ahrefs-Projekts bedient. Jeder Fastly-Tarif funktioniert, einschließlich des kostenlosen Tarifs.
- Berechtigung, die Konfiguration dieses Services zu bearbeiten und eine neue Version zu aktivieren.
Schritt 1 – Zugriffsschlüssel abrufen
- Gehe in Ahrefs für dein Projekt zu Projekteinstellungen → Bot Analytics.
- Fastly auswählen.
- Kopiere die URL, den Namen des benutzerdefinierten Headers und den Wert des benutzerdefinierten Headers. Der Header-Wert ist dein Zugriffsschlüssel: Er identifiziert dein Projekt, also behandle ihn wie ein Passwort.
Alles andere, was du brauchst, findest du auf dieser Seite.
Schritt 2 – Logging-Endpunkt hinzufügen
Öffne im Fastly-Kontrollpanel deinen Service, klicke auf Konfiguration bearbeiten und klone die aktive Version. Wähle im linken Menü Logging, dann HTTPS und Endpunkt erstellen.
Endpunktfelder
| Feld | Wert |
|---|---|
| Name | Ahrefs Bot Analytics |
| Platzierung | Standard-Formatversion |
| Log-Format | Das unten stehende Log-Format, das das Standardformat ersetzt |
| URL | https://analytics.ahrefs.com/api/fastly/logs |
| Maximale Logs, Maximale Bytes | Leer lassen |
| Content-Typ | application/json |
| Name des benutzerdefinierten Headers | X-Ahrefs-Web-Analytics-Property |
| Wert des benutzerdefinierten Headers | Der Zugriffsschlüssel aus Schritt 1 |
| Methode | POST |
| JSON-Logeintragsformat | Durch Zeilenumbrüche getrennt. Ein JSON-Array funktioniert ebenfalls. |
| Komprimierung | Gzip (empfohlen) oder keine. Zstd und Snappy werden nicht akzeptiert. |
| TLS-Felder | Leer lassen |
Lege unter Advanced-Optionen die Option Logzeilenformat auswählen auf Leer fest. Klicke auf Erstellen und dann auf Aktivieren, um die neue Version zu aktivieren. Fastly beginnt sofort mit dem Streaming.
warning
Das Logzeilenformat muss Leer sein. Das Standardformat Klassisch stellt jeder Zeile einen Syslog-Header voran, und Ahrefs lehnt diese Batches ab.
info
Wenn du den Endpunkt speicherst, prüft Fastly, ob der Zielhost Logs von Fastly-Services akzeptiert. Ahrefs beantwortet diese Prüfung für alle, daher musst du auf deiner Seite nichts konfigurieren.
Log-Format
Fastly füllt die Platzhalter %{...}V für jede Anfrage aus. Du entscheidest, was du teilst: Das minimale Format reicht aus, damit Bot Analytics funktioniert; das empfohlene Format liefert bessere Ergebnisse. Unbekannte Schlüssel werden ignoriert, daher kannst du zusätzliche Felder beibehalten, die du bereits loggst.
Minimal. Bot-Besuche mit Zeit, Seite und Bot-Namen:
{
"timestamp": %{time.start.msec}V,
"host": "%{if(req.http.Fastly-Orig-Host, req.http.Fastly-Orig-Host, req.http.Host)}V",
"url": "%{json.escape(req.url)}V",
"request_user_agent": "%{json.escape(req.http.User-Agent)}V"
}
Empfohlen. Fügt die IP-Adresse des Besuchers für Standortdaten, den Status und die bei jedem Besuch angezeigten Antwortdetails, die Web-Bot-Auth-Verifizierung sowie den Edge-Marker hinzu, der Duplikate entfernt, wenn dein Service Shielding verwendet:
{
"timestamp": %{time.start.msec}V,
"client_ip": "%{req.http.Fastly-Client-IP}V",
"host": "%{if(req.http.Fastly-Orig-Host, req.http.Fastly-Orig-Host, req.http.Host)}V",
"scheme": "%{req.protocol}V",
"url": "%{json.escape(req.url)}V",
"request_method": "%{json.escape(req.method)}V",
"request_referer": "%{json.escape(req.http.Referer)}V",
"request_user_agent": "%{json.escape(req.http.User-Agent)}V",
"response_state": "%{json.escape(fastly_info.state)}V",
"response_status": %{resp.status}V,
"response_body_size": %{resp.body_bytes_written}V,
"response_content_type": "%{json.escape(resp.http.Content-Type)}V",
"fastly_server": "%{json.escape(server.identity)}V",
"fastly_is_edge": %{if(fastly.ff.visits_this_service == 0, "true", "false")}V,
"request_id": "%{json.escape(req.xid)}V",
"signature": "%{json.escape(req.http.Signature)}V",
"signature_input": "%{json.escape(req.http.Signature-Input)}V",
"signature_agent": "%{json.escape(req.http.Signature-Agent)}V"
}
Kombiniere die beiden nach Belieben: Die vier minimalen Schlüssel sind erforderlich; alle anderen Schlüssel können weggelassen werden oder leer bzw. (null) sein. Behalte fastly_is_edge immer bei, wenn dein Service einen Shield hat; andernfalls wird jeder Miss doppelt gezählt. Die nicht in Anführungszeichen gesetzten Schlüssel (timestamp, response_status, response_body_size, fastly_is_edge) müssen immer einen Wert haben, sonst ist die Zeile kein gültiges JSON.
info
Fastly-Compute-Services schreiben dasselbe JSON aus dem Code, ein Objekt pro Zeile, mit den Endpunkt-Einstellungen aus Schritt 2.
Schritt 3 — Verifizieren
Fastly liefert Logs in kleinen Batches, meist innerhalb einer Minute nach den Requests. Bot-Besuche erscheinen dann wenige Minuten später im Bot-Analytics-Report. Requests von Browsern werden ebenfalls gesendet; Ahrefs verwirft alles, was kein Bot ist.
Fehlerbehebung
Fastly zeigt im Kontrollpanel keine Zustellfehler für HTTPS-Endpunkte an. Prüfe daher die Einstellungen anhand der Tabelle oben, wenn nichts ankommt. Ahrefs beantwortet jeden Batch mit einer der folgenden Antworten:
| Antwort | Ursache |
|---|---|
401 missing authentication header | Der benutzerdefinierte Header-Name ist falsch geschrieben oder leer. |
403 invalid authentication | Der benutzerdefinierte Header-Wert stimmt nicht mit einem Ahrefs-Projekt überein. Kopiere ihn erneut aus Schritt 1. |
400 record 0: … | Das Log-Zeilenformat ist Klassisch statt Leer, die Komprimierung ist weder auf Gzip noch auf „Keine“ eingestellt, oder das Log-Format ist kein gültiges JSON. |
400 record N: Missing record field … | Durch Zeilenumbrüche getrennt: Im Log-Format fehlt einer der erforderlichen Schlüssel. |
400 invalid body: not a JSON array of log records: … | JSON-Array: Das Log-Zeilenformat ist Klassisch statt Leer, im Log-Format fehlt ein erforderlicher Schlüssel oder das Log-Format ist kein gültiges JSON. |
400 body is not valid gzip | Die Komprimierung ist in Fastly auf Gzip gesetzt, aber der Body konnte nicht dekomprimiert werden. |