LOADING...

Autres jeux (API REST)

L'intégration API est réservée au propriétaire du serveur de jeux.

Si votre jeu n'a pas de plugin dédié, vous pouvez intégrer QuantumLogs via l'API REST directement. Cette méthode fonctionne avec n'importe quel langage de programmation.

Endpoint

POST /logs

Authentification

Envoyez votre clé API dans le header Authorization :

Authorization: votre-cle-api-ici

La clé est envoyée directement dans le header, sans préfixe Bearer. C'est le format attendu par QuantumLogs.

Format de la requête

Le body est un tableau JSON de logs. Chaque élément du tableau est un objet log :

[
  {
    "measurement": "player_kill",
    "timestamp": "2025-01-15T14:30:45.123Z",
    "tags": {
      "player_name": "John",
      "player_id": "12345",
      "player_global_id": "76561198000000000",
      "target_name": "Jane",
      "target_id": "67890",
      "target_global_id": "76561198000000001",
      "server": "serveur-1"
    },
    "fields": {
      "value": "John a tué Jane avec AK-47 à 50m (headshot)"
    },
    "metadata": {
      "weapon": "AK-47",
      "distance": 50,
      "bodypart": "head"
    }
  }
]

Champs détaillés

Champs obligatoires

ChampTypeDescription
measurementstringType/catégorie du log (ex: kill, chat, connect)
timestampstring (ISO 8601)Horodatage du log (ex: 2025-01-15T14:30:45.123Z)
fieldsobjectObjet contenant le champ value
fields.valuestringContenu textuel du log (c'est ce qui s'affiche dans la colonne "Valeur")
tagsobjectObjet contenant les tags d'indexation (peut être vide {})

Tous ces champs sont obligatoires. L'objet tags doit être présent même s'il est vide ({}). Le timestamp doit être au format ISO 8601 — il n'y a pas de valeur par défaut côté serveur.

Tags reconnus par le backend

Seuls les noms de tags listés ci-dessous sont reconnus. Tout tag avec un nom différent sera silencieusement ignoré et n'apparaîtra pas dans vos logs. C'est la cause la plus fréquente de "logs qui ne fonctionnent pas".

TagTypeDescription
player_namestringNom du joueur
player_idstringID du joueur (spécifique au serveur, ex: ID de personnage)
player_global_idstringIdentifiant unique global du joueur (Steam ID 64, UUID, etc.)
player_steamidstringSteam ID (déprécié, utilisez player_global_id)
target_namestringNom de la cible
target_idstringID de la cible
target_global_idstringIdentifiant unique global de la cible
target_steamidstringSteam ID de la cible (déprécié)
serverstringIdentifiant du serveur source

Tous les tags sont optionnels, mais server est fortement recommandé — il est utilisé pour le comptage de serveurs actifs et le contrôle des limites de votre plan.

Exemples de tags invalides (seront ignorés) :

  • weapon, distance, map → Mettez ces infos dans fields.value ou dans metadata
  • attacker_name, victim_name → Utilisez player_name et target_name
  • admin_name → Utilisez player_name

Champs optionnels

ChampTypeDescription
metadataobjectDonnées JSON supplémentaires libres (visible dans le détail du log, non filtrable)

Codes de réponse

Succès

CodeBodyDescription
201OKLogs reçus et insérés avec succès

Erreurs

CodeDescriptionDétail
401Clé API invalide ou manquante{ "statusCode": 401, "message": "Missing authorization header" } ou { "statusCode": 401, "message": "Invalid API key" }
413Body trop volumineuxLa taille maximale du body est de 50 Mo
429Limite de serveurs dépasséeVoir détail ci-dessous
500Erreur serveurInjection bloquée (plan expiré/suspendu) ou erreur de base de données

Détail de la réponse 429

Si vous dépassez le nombre de serveurs autorisés par votre plan, la réponse contient des informations utiles :

{
  "statusCode": 429,
  "error": "Server Limit Exceeded",
  "message": "You have reached your server limit (5). Upgrade your plan to add more servers.",
  "upgradeUrl": "https://quantumlogs.com/pricing",
  "activeServers": ["rp-1", "rp-2", "pvp-1", "event-1", "test"],
  "maxServers": 5
}

Les serveurs actifs sont suivis pendant 24 heures. Un serveur qui n'envoie plus de logs pendant 24h libère automatiquement une place.

Bonnes pratiques

Envoi par lots

Envoyez vos logs par lots plutôt qu'un par un. Un intervalle de 10 secondes est recommandé :

  1. Accumulez les logs dans une file d'attente en mémoire
  2. Toutes les 10 secondes, envoyez le lot complet en une seule requête
  3. Videz la file après un envoi réussi

Tout dans fields.value

Le champ value est le contenu principal de votre log. Mettez-y toutes les informations lisibles. Les tags ne servent qu'à l'indexation (recherche par joueur, serveur, etc.).

// CORRECT - toutes les infos dans value
{
  "measurement": "player_kill",
  "timestamp": "2025-01-15T14:30:45.123Z",
  "fields": { "value": "John a tué Jane avec AK-47 à 50m (headshot)" },
  "tags": { "player_name": "John", "target_name": "Jane", "server": "rp-1" }
}
// INCORRECT - les données custom dans les tags sont ignorées
{
  "measurement": "player_kill",
  "timestamp": "2025-01-15T14:30:45.123Z",
  "tags": { "weapon": "AK-47", "distance": "50", "bodypart": "head" },
  "fields": { "value": "" }
}

Metadata pour les données structurées

Si vous avez besoin de stocker des données structurées en plus du texte, utilisez metadata :

{
  "measurement": "player_kill",
  "timestamp": "2025-01-15T14:30:45.123Z",
  "fields": { "value": "John a tué Jane avec AK-47 à 50m (headshot)" },
  "tags": { "player_name": "John", "target_name": "Jane", "server": "rp-1" },
  "metadata": {
    "weapon": "AK-47",
    "distance": 50,
    "bodypart": "head",
    "position": { "x": 1234.5, "y": -567.89, "z": 100.23 }
  }
}

Les métadonnées sont stockées en JSON et visibles dans le détail du log, mais ne sont pas filtrables via les filtres classiques.

Gestion des erreurs

  • En cas d'erreur réseau, conservez les logs en mémoire et réessayez
  • Implémentez un retry avec backoff exponentiel
  • Envoyez les logs restants à l'arrêt du serveur (flush)

Exemples

cURL

curl -X POST https://votre-instance.quantumlogs.cloud/logs \
  -H "Content-Type: application/json" \
  -H "Authorization: votre-cle-api" \
  -d '[{
    "measurement": "test",
    "timestamp": "'$(date -u +%Y-%m-%dT%H:%M:%S.000Z)'",
    "fields": { "value": "Log de test depuis cURL" },
    "tags": { "server": "test-server" }
  }]'

Python

import requests
import json
from datetime import datetime, timezone

API_URL = "https://votre-instance.quantumlogs.cloud/logs"
API_KEY = "votre-cle-api"

logs = [{
    "measurement": "player_connection",
    "timestamp": datetime.now(timezone.utc).isoformat(),
    "tags": {
        "player_name": "John",
        "player_global_id": "76561198000000000",
        "server": "serveur-1"
    },
    "fields": {
        "value": "John s'est connecté au serveur"
    }
}]

response = requests.post(
    API_URL,
    headers={
        "Content-Type": "application/json",
        "Authorization": API_KEY
    },
    json=logs
)

print(f"Status: {response.status_code}")  # 201 = succès
print(f"Body: {response.text}")            # "OK"

JavaScript (Node.js)

const API_URL = "https://votre-instance.quantumlogs.cloud/logs";
const API_KEY = "votre-cle-api";

const logs = [{
  measurement: "player_connection",
  timestamp: new Date().toISOString(),
  tags: {
    player_name: "John",
    player_global_id: "76561198000000000",
    server: "serveur-1"
  },
  fields: {
    value: "John s'est connecté au serveur"
  }
}];

const response = await fetch(API_URL, {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Authorization": API_KEY
  },
  body: JSON.stringify(logs)
});

console.log(`Status: ${response.status}`);  // 201 = succès
console.log(`Body: ${await response.text()}`); // "OK"

C# (Unity / .NET)

using System.Net.Http;
using System.Text;
using System.Text.Json;

var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "votre-cle-api");

var logs = new[] {
    new {
        measurement = "player_connection",
        timestamp = DateTime.UtcNow.ToString("o"),
        tags = new { player_name = "John", server = "serveur-1" },
        fields = new { value = "John s'est connecté" }
    }
};

var content = new StringContent(
    JsonSerializer.Serialize(logs),
    Encoding.UTF8,
    "application/json"
);

var response = await client.PostAsync(
    "https://votre-instance.quantumlogs.cloud/logs",
    content
);

Console.WriteLine($"Status: {(int)response.StatusCode}"); // 201 = succès

Lua (Garry's Mod - exemple custom)

local API_URL = "https://votre-instance.quantumlogs.cloud/logs"
local API_KEY = "votre-cle-api"

local logs = {
    {
        measurement = "player_chat",
        timestamp = os.date("!%Y-%m-%dT%H:%M:%S.000Z"),
        tags = {
            player_name = "John",
            player_global_id = "76561198000000000",
            server = "darkrp-1"
        },
        fields = {
            value = "John: Bonjour tout le monde !"
        }
    }
}

HTTP({
    url = API_URL,
    method = "POST",
    headers = {
        ["Content-Type"] = "application/json",
        ["Authorization"] = API_KEY
    },
    body = util.TableToJSON(logs),
    success = function(code, body)
        print("QuantumLogs: " .. code) -- 201 = succès
    end,
    failed = function(reason)
        print("QuantumLogs Error: " .. reason)
    end
})