PulseRadarDocumentation

Documentation PulseRadar

Observabilité complète pour vos serveurs — logs, métriques, APM, error tracking et traces distribuées, hébergé en France.

Démarrage rapide

Connectez votre premier serveur en moins de 2 minutes.

1. Créez une clé API

Rendez-vous dans Dashboard → Clés API, cliquez sur Nouvelle clé. Copiez la clé affichée — elle ne sera plus visible ensuite.

2. Installez l'agent

Sur votre serveur Linux, lancez en root :

bash
curl -sSL https://pulseradar.cloud/install | bash -s -- --api-key <VOTRE_CLÉ>

L'agent détecte automatiquement les services actifs (Nginx, MySQL, PHP-FPM…) et configure Fluent Bit pour les surveiller.

3. Vérifiez dans le dashboard

Votre serveur apparaît dans Dashboard → Serveurs avec un point vert dans les 30 secondes. Les logs et métriques arrivent en temps réel.

Pour envoyer des logs depuis une application sans agent, utilisez l'API d'ingestion directement.

Agent & installation

L'agent PulseRadar est un binaire Go léger (~10 Mo) qui collecte les métriques système et orchestre Fluent Bit pour la collecte des logs applicatifs.

Installation Linux

bash
# Installation automatique (recommandée)
curl -sSL https://pulseradar.cloud/install | bash -s -- --api-key <CLÉ>

# Options disponibles
--api-key <CLÉ>        Clé API (obligatoire)
--server-name <NOM>    Nom affiché dans le dashboard (défaut: hostname)

Installation Windows

powershell
# PowerShell en administrateur
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
iex (New-Object Net.WebClient).DownloadString('https://pulseradar.cloud/install.ps1')

Ce que fait l'agent

FonctionFréquenceDétail
Métriques systèmeToutes les 10sCPU, RAM, swap, disk I/O, réseau
HeartbeatToutes les 30sStatut online/offline dans le dashboard
Logs applicatifsTemps réelVia Fluent Bit (tail des fichiers log)
Mise à jour autoAu démarrageVérifie et télécharge les nouvelles versions

Gestion du service

bash
# Statut
sudo systemctl status pulseradar-agent

# Redémarrage
sudo systemctl restart pulseradar-agent

# Logs de l'agent
sudo journalctl -u pulseradar-agent -f

Fichiers de configuration

/etc/pulseradar/agent.conf        Configuration de l'agent
/etc/fluent-bit/fluent-bit.conf Configuration Fluent Bit (auto-généré)
/etc/fluent-bit/parsers.conf    Parseurs de logs
L'agent enregistre automatiquement le serveur dans votre compte via la clé API. Le SERVER_ID est stocké dans /etc/pulseradar/agent.conf.

Ingestion de logs

PulseRadar accepte les logs via HTTP JSON. Chaque événement est normalisé et stocké dans ClickHouse.

Format d'un événement

json
{
  "level":     "error",          // fatal|critical|error|warning|info|debug
  "message":   "Connection refused to database",
  "source":    "mon-app",        // identifiant libre de la source
  "timestamp": "2026-03-30T14:00:00Z",  // optionnel, défaut: maintenant
  "host":      "web01",          // optionnel
  "fields": {                    // données structurées libres
    "user_id": "42",
    "duration_ms": "320"
  }
}

Envoyer un log

bash
# Log unique
curl -X POST https://ingest.pulseradar.cloud/v1/logs \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{"level":"error","message":"Oops","source":"mon-app"}'

# Batch (jusqu'à 500 événements par requête)
curl -X POST https://ingest.pulseradar.cloud/v1/logs \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '[{"level":"info","message":"Start"},{"level":"error","message":"Fail"}]'

Niveaux de log

NiveauAlias acceptésCouleur dashboard
criticalfatalRouge vif
errorerr, exceptionRouge
warningwarnOrange
infoBleu
debugtraceGris
Les logs info et debug sont filtrés par défaut pour économiser le quota. Activez Conserver les logs info dans les paramètres du projet pour les stocker.

SDKs officiels

Envoyez des logs directement depuis votre code applicatif, sans agent. Tous les SDKs sont disponibles en téléchargement sur pulseradar.cloud/sdk.

Concepts communs à tous les SDKs

ParamètreRequisDescription
api_keyOuiClé API (pr_xxx). Variable d'env recommandée : PULSERADAR_API_KEY
sourceRecommandéIdentifiant de votre app (ex: mon-api, frontend, worker)
server_idOptionnelUUID du serveur — lie les logs au serveur dans le dashboard. Récupérez-le depuis /etc/pulseradar/agent.conf ou GET /api/servers
endpointNonURL d'ingestion (défaut: https://ingest.pulseradar.cloud/v1/logs)

Niveaux de log

NiveauMéthodeFacturé
critical.critical()Toujours
error.error()Toujours
warning.warning()Toujours
info.info()Seulement si keep_info activé
debug.debug()Seulement si keep_info activé

Fonctionnalités communes

Tous les SDKs supportent :

  • Batch queue — les logs sont groupés et envoyés toutes les 5s ou tous les 50 logs
  • captureException — capture une exception avec stack trace (5 frames max)
  • Fields / metadata — données structurées libres (user_id, request_id, etc.)
  • Flush / Close — vide la queue manuellement (important pour les scripts courts)
  • Header X-Server-Id — envoyé automatiquement si server_id est configuré
Appelez toujours flush() ou close() avant la fin de votre programme (scripts CLI, Lambda, cron jobs), sinon les derniers logs en queue seront perdus.

Node.js

bash
# Télécharger
curl -O https://pulseradar.cloud/sdk/nodejs/index.js
js
const PulseRadar = require('./index.js') // ou le chemin vers le fichier

const logger = new PulseRadar({
  apiKey:   process.env.PULSERADAR_API_KEY,
  serverId: process.env.PULSERADAR_SERVER_ID, // optionnel
  source:   'mon-api',
})

// Logs avec fields
logger.info('Serveur démarré', { port: '3000', env: 'production' })
logger.error('Erreur DB', { query: 'SELECT ...', duration_ms: '320' })

// Capture d'exception avec stack trace
try {
  riskyOperation()
} catch (err) {
  logger.captureException(err, { user_id: '42', route: '/api/users' })
}

// Express middleware — capture globale des erreurs
app.use((err, req, res, next) => {
  logger.captureException(err, { path: req.path, method: req.method })
  res.status(500).json({ error: 'Internal error' })
})

// IMPORTANT : flush avant exit (scripts, Lambda)
process.on('beforeExit', () => logger.flush())

Python

bash
# Télécharger
mkdir -p pulseradar
curl -o pulseradar/__init__.py https://pulseradar.cloud/sdk/python/pulseradar/__init__.py
python
from pulseradar import PulseRadar
import os

logger = PulseRadar(
    api_key=os.environ["PULSERADAR_API_KEY"],
    server_id=os.environ.get("PULSERADAR_SERVER_ID"),
    source="mon-api",
)

# Logs avec fields (kwargs)
logger.info("Démarrage", version="1.0", port="8000")
logger.error("Erreur DB", query="SELECT ...", duration_ms="320")

# Capture d'exception (utilise sys.exc_info si pas d'argument)
try:
    risky()
except Exception:
    logger.capture_exception(user_id="42")

# Django middleware
class PulseRadarMiddleware:
    def process_exception(self, request, exception):
        logger.capture_exception(exception, path=request.path)

# Flask error handler
@app.errorhandler(Exception)
def handle_error(e):
    logger.capture_exception(e)
    return "Error", 500

# IMPORTANT : flush en fin de script
import atexit
atexit.register(logger.flush)

PHP

bash
# Télécharger
curl -O https://pulseradar.cloud/sdk/php/src/PulseRadar.php
php
require_once __DIR__ . '/PulseRadar.php';
use PulseRadar\PulseRadar;

$logger = new PulseRadar([
    'api_key'   => getenv('PULSERADAR_API_KEY'),
    'server_id' => getenv('PULSERADAR_SERVER_ID'),
    'source'    => 'mon-api',
    'async'     => true,  // batch + flush au __destruct
]);

$logger->info('Démarrage');
$logger->error('Erreur DB', ['query' => 'SELECT ...', 'duration_ms' => '320']);

// Capture d'exception
try {
    risky();
} catch (\Throwable $e) {
    $logger->captureException($e, ['user_id' => '42']);
}

// Laravel : dans app/Exceptions/Handler.php
public function report(\Throwable $e) {
    app(PulseRadar::class)->captureException($e);
    parent::report($e);
}

Ruby

bash
curl -O https://pulseradar.cloud/sdk/ruby/lib/pulseradar.rb
ruby
require_relative 'pulseradar'

logger = PulseRadar::Client.new(
  api_key:   ENV['PULSERADAR_API_KEY'],
  server_id: ENV['PULSERADAR_SERVER_ID'],
  source:    'mon-api',
)

logger.info('Démarrage', port: '3000')
logger.error('Erreur DB', query: 'SELECT ...')

# Capture d'exception
begin
  risky_operation
rescue => e
  logger.capture_exception(e, user_id: '42')
end

# Rails : dans config/initializers/pulseradar.rb
Rails.application.config.middleware.use(proc { |env|
  begin
    @app.call(env)
  rescue => e
    PULSERADAR.capture_exception(e, path: env['PATH_INFO'])
    raise
  end
})

Java / Spring Boot

bash
# Télécharger
curl -O https://pulseradar.cloud/sdk/java/src/main/java/cloud/pulseradar/PulseRadar.java
curl -O https://pulseradar.cloud/sdk/java/src/main/java/cloud/pulseradar/PulseRadarLogbackAppender.java
java
// Usage direct
PulseRadar logger = new PulseRadar.Builder()
    .apiKey(System.getenv("PULSERADAR_API_KEY"))
    .serverId(System.getenv("PULSERADAR_SERVER_ID"))
    .source("mon-api")
    .build();

logger.info("Server started", Map.of("port", "8080"));
logger.error("DB failed", Map.of("query", "SELECT ..."));

try { riskyOperation(); }
catch (Exception e) { logger.captureException(e, Map.of("user_id", "42")); }

// IMPORTANT : flush au shutdown
Runtime.getRuntime().addShutdownHook(new Thread(logger::flush));

Ou via Logback appender (zéro code, Spring Boot / tout projet SLF4J) :

xml
<!-- src/main/resources/logback.xml -->
<appender name="PULSERADAR" class="cloud.pulseradar.PulseRadarLogbackAppender">
  <apiKey>${PULSERADAR_API_KEY}</apiKey>
  <source>mon-api</source>
  <serverId>${PULSERADAR_SERVER_ID}</serverId>
</appender>
<root level="WARN">
  <appender-ref ref="PULSERADAR" />
</root>
Avec le Logback appender, tous les logs WARN+ sont automatiquement envoyés à PulseRadar. Les exceptions loguées via log.error("msg", exception) incluent automatiquement la stack trace.

Go

bash
# Télécharger
mkdir -p pulseradar && cd pulseradar
curl -O https://pulseradar.cloud/sdk/go/pulseradar.go
curl -O https://pulseradar.cloud/sdk/go/slog.go
curl -O https://pulseradar.cloud/sdk/go/go.mod
go
package main

import (
    "log/slog"
    "os"
    pulseradar "./pulseradar" // chemin local
)

func main() {
    client := pulseradar.New(os.Getenv("PULSERADAR_API_KEY"),
        pulseradar.WithSource("mon-api"),
        pulseradar.WithServerID(os.Getenv("PULSERADAR_SERVER_ID")),
    )
    defer client.Close() // flush les logs restants

    client.Info("Démarrage", pulseradar.F("port", "8080"))
    client.Error("Erreur DB", pulseradar.F("query", "SELECT ..."))

    if err := riskyOperation(); err != nil {
        client.CaptureException(err, pulseradar.F("user_id", "42"))
    }

    // Intégration log/slog (Go 1.21+)
    logger := slog.New(pulseradar.NewSlogHandler(client))
    slog.SetDefault(logger)
    slog.Info("Hello from slog", "key", "value")
}

// Gin middleware
func PulseRadarMiddleware(client *pulseradar.Client) gin.HandlerFunc {
    return func(c *gin.Context) {
        c.Next()
        for _, err := range c.Errors {
            client.CaptureException(err.Err, pulseradar.F("path", c.FullPath()))
        }
    }
}

.NET / C#

bash
curl -O https://pulseradar.cloud/sdk/dotnet/PulseRadar/PulseRadar.cs
csharp
using PulseRadar;

var logger = new PulseRadarClient(
    apiKey: Environment.GetEnvironmentVariable("PULSERADAR_API_KEY")!,
    source: "mon-api",
    serverId: Environment.GetEnvironmentVariable("PULSERADAR_SERVER_ID")
);

logger.Info("Démarrage", new() { ["port"] = "5000" });
logger.Error("Erreur DB", new() { ["query"] = "SELECT ..." });

try { RiskyOperation(); }
catch (Exception ex) { logger.CaptureException(ex, new() { ["user_id"] = "42" }); }

// ASP.NET Core : dans Program.cs
app.Use(async (context, next) => {
    try { await next(); }
    catch (Exception ex) {
        logger.CaptureException(ex, new() { ["path"] = context.Request.Path });
        throw;
    }
});

// IMPORTANT : dispose en fin de vie
using var logger = new PulseRadarClient(...);

Rust

bash
mkdir -p pulseradar/src && cd pulseradar
curl -O https://pulseradar.cloud/sdk/rust/Cargo.toml
curl -o src/lib.rs https://pulseradar.cloud/sdk/rust/src/lib.rs
rust
use pulseradar::{Client, Field};

let client = Client::new("pr_your_api_key")
    .source("mon-api")
    .server_id("optional-server-id");

client.info("Démarrage", &[Field::new("port", "8080")]);
client.error("Erreur DB", &[Field::new("query", "SELECT ...")]);

// Capture d'erreur
client.capture_error(&some_error, &[Field::new("user_id", "42")]);

// Le client flush automatiquement au drop
drop(client);
server_id — récupérez-le depuis /etc/pulseradar/agent.conf sur le serveur où tourne votre app, ou via GET /api/servers. Cela permet de voir les logs applicatifs dans le dashboard du serveur, corrélés avec les métriques infra.

Sources supportées

L'agent configure automatiquement Fluent Bit pour les services détectés.

SourceValeur sourceFonctionnalités
journaldjournaldTous les services systemd (filet universel)
auth.logauthSSH, sudo, PAM — audit sécurité
NginxnginxLogs accès + APM Web + métriques
ApacheapacheLogs accès + APM Web + métriques
MySQLmysqlSlow query log + fingerprinting SQL
PostgreSQLpostgresSlow query log + fingerprinting SQL
PHP-FPMphp-fpmSlow log + saturation + stack trace
Dockerdockerstdout/stderr des conteneurs
RedisredisLogs erreur
HAProxyhaproxyLogs accès
SyslogsyslogLogs système kernel/auth
RabbitMQrabbitmqLogs erreur, métriques queues/consumers
ElasticsearchelasticsearchLogs cluster, métriques health/shards/JVM
CroncronJobs planifiés, erreurs silencieuses
UFWufwLogs firewall, scans de ports
CustomlibreVia API directe ou Fluent Bit personnalisé

Ajouter une source personnalisée

Dans /etc/fluent-bit/fluent-bit.conf, ajoutez un bloc INPUT et FILTER :

ini
[INPUT]
    Name   tail
    Path   /var/log/mon-app/*.log
    Tag    mon-app

[FILTER]
    Name   record_modifier
    Match  mon-app
    Record source mon-app
    Record server_id ${SERVER_ID}
    Record project_id ${PROJECT_ID}

[OUTPUT]
    Name        http
    Match       mon-app
    Host        ingest.pulseradar.cloud
    Port        443
    URI         /v1/logs/fluent-bit
    Format      json
    Header      Authorization Bearer ${API_KEY}

Métriques serveur

L'agent collecte les métriques système toutes les 10 secondes et les pousse vers l'API.

Métriques collectées

MétriqueUnitéDescription
cpu_pct%Utilisation CPU (moyenne tous cœurs)
mem_pct%RAM utilisée / RAM totale
swap_pct%Swap utilisé / Swap total
load1floatLoad average 1 minute
disk_read_bpsbytes/sDébit lecture disque
disk_write_bpsbytes/sDébit écriture disque
net_recv_bpsbytes/sBande passante entrante
net_sent_bpsbytes/sBande passante sortante
disk_used_pct%Espace disque utilisé

Visualisation

Accédez aux graphes dans Serveur → Système. Fenêtres disponibles : 1h, 3h, 12h, 24h avec points à la minute.

Vue Corrélation

La page Serveur → Corrélation superpose les métriques système (CPU, RAM) avec les métriques HTTP (req/s, latence P99) pour identifier les saturations liées au trafic.

APM Web (Nginx / Apache)

PulseRadar agrège automatiquement les access logs Nginx et Apache en métriques de performance à la minute, sans modifier votre configuration de logs.

Métriques APM calculées

MétriqueDescription
req_countNombre de requêtes
err_4xx / err_5xxErreurs client / serveur
avg_ms / p50 / p75 / p99Latence (depuis nginx request_time)
count_fast / ok / slow< 500ms / 500ms–2s / > 2s
bytes_outBande passante sortante
top_ips5 IPs les plus actives par minute

Format de log Nginx requis

Ajoutez ce format dans votre nginx.conf pour activer la latence :

nginx
log_format pulseradar '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent" '
                    'rt=$request_time';

access_log /var/log/nginx/access.log pulseradar;

Score de santé

ScoreCondition
✅ BonTaux erreur < 1% ET P99 < 500ms
⚠️ MoyenTaux erreur < 5% OU P99 < 2s
🔴 DégradéTaux erreur > 5% OU P99 > 2s
En mode agrégé, les logs 2xx/3xx ne sont pas stockés dans ClickHouse, seules les métriques le sont. Les erreurs 4xx/5xx restent visibles dans les logs. Cela réduit significativement votre quota.

DB APM (MySQL / PostgreSQL / PHP-FPM)

PulseRadar parse les slow logs de base de données, fingerprinte les requêtes SQL et agrège les statistiques par minute.

MySQL — configuration

ini
# /etc/mysql/mysql.conf.d/mysqld.cnf
slow_query_log        = 1
slow_query_log_file   = /var/log/mysql/slow.log
long_query_time       = 0.5      # requêtes > 500ms
log_queries_not_using_indexes = 1

PostgreSQL — configuration

ini
# /etc/postgresql/*/main/postgresql.conf
log_min_duration_statement = 500   # ms — requêtes > 500ms
log_line_prefix = '%t [%p]: [%l-1] user=%u,db=%d,app=%a,client=%h '

PHP-FPM — configuration

L'agent ajoute automatiquement ces lignes dans le pool PHP-FPM :

ini
slowlog = /var/log/php-fpm-slow.log
request_slowlog_timeout = 2s

Métriques DB APM

MétriqueDescription
fingerprintRequête normalisée (littéraux remplacés par ?)
call_countNombre d'exécutions sur la période
avg_ms / max_msDurée moyenne / maximale
rows_examinedLignes analysées (MySQL uniquement)
rows_sentLignes retournées (MySQL uniquement)

Fingerprinting SQL

Les requêtes sont normalisées pour regrouper les variantes identiques :

Avant :  SELECT * FROM users WHERE id = 42 AND status = 'active'
Après :  SELECT * FROM users WHERE id = ? AND status = ?

Avant :  SELECT * FROM orders WHERE id IN (1, 2, 3, 4, 5)
Après :  SELECT * FROM orders WHERE id IN (?)

Error Tracking

PulseRadar regroupe automatiquement les erreurs identiques en groupes d'erreurs, avec compteur de fréquence, détection de régression et stack trace colorée.

Fonctionnement

Chaque log error ou critical est normalisé (UUIDs, IPs, nombres remplacés) puis hashé. Les occurrences du même hash incrémentent le même groupe.

États d'un groupe

ÉtatSignificationAction
ActifErreur toujours présenteRésoudre / Ignorer
RésoluMarqué comme corrigéRouvre si réapparaît (Régression)
IgnoréSupprimé de la vue activeRouvre si réapparaît (Régression)
Régression 🔴Réapparu après résolution/ignoréTraiter en priorité

Protection anti-flood

Une même erreur génère au maximum 100 événements facturés par heure. Au-delà, seul le compteur du groupe est mis à jour — l'événement n'est pas stocké dans ClickHouse et n'est pas comptabilisé dans votre quota mensuel.

Accès

Les groupes d'erreurs sont visibles à deux niveaux :

  • Serveur → Erreurs — erreurs de ce serveur spécifique
  • Projet → Erreurs — toutes les erreurs du compte

Traces distribuées (OTLP)

PulseRadar accepte les spans OpenTelemetry au format OTLP/HTTP JSONet les visualise en waterfall.

Endpoint

POST https://ingest.pulseradar.cloud/v1/traces
Authorization: Bearer <API_KEY>
X-Server-Id: <SERVER_ID>
Content-Type: application/json

Configuration par langage

Variables d'environnement (universel)

bash
export OTEL_EXPORTER_OTLP_ENDPOINT=https://ingest.pulseradar.cloud
export OTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer <API_KEY>,X-Server-Id=<SERVER_ID>"
export OTEL_EXPORTER_OTLP_PROTOCOL=http/json
export OTEL_SERVICE_NAME=mon-app

Node.js

bash
npm install @opentelemetry/sdk-node @opentelemetry/exporter-trace-otlp-http
js
const { NodeSDK } = require('@opentelemetry/sdk-node')
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http')

new NodeSDK({
  traceExporter: new OTLPTraceExporter({
    url: 'https://ingest.pulseradar.cloud/v1/traces',
    headers: {
      'Authorization': 'Bearer <API_KEY>',
      'X-Server-Id': '<SERVER_ID>',
    },
  }),
  serviceName: 'mon-app',
}).start()

Python

bash
pip install opentelemetry-sdk opentelemetry-exporter-otlp-proto-http
python
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter

provider.add_span_processor(BatchSpanProcessor(OTLPSpanExporter(
    endpoint="https://ingest.pulseradar.cloud/v1/traces",
    headers={"Authorization": "Bearer <API_KEY>", "X-Server-Id": "<SERVER_ID>"}
)))

PHP (Laravel)

bash
composer require open-telemetry/sdk open-telemetry/exporter-otlp
ini
# .env
OTEL_PHP_AUTOLOAD_ENABLED=true
OTEL_EXPORTER_OTLP_ENDPOINT=https://ingest.pulseradar.cloud
OTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer <API_KEY>,X-Server-Id=<SERVER_ID>"

Données collectées par span

Attribut OTLPAffiché comme
service.nameService
span.name / operationOpération
http.method + http.urlRequête HTTP
http.status_codeCode HTTP
db.system + db.statementRequête DB
duration (start→end)Durée en ms
status.code = 2Erreur (rouge)

Rétention des traces : 7 jours.

Hyperviseurs

PulseRadar collecte les métriques de vos hyperviseurs pour corréler les performances des VMs avec les logs applicatifs.

Proxmox VE

Ajoutez les variables dans /etc/pulseradar/agent.conf :

bash
PROXMOX_HOST=https://pve.example.com:8006
PROXMOX_TOKEN_ID=root@pam!monitoring
PROXMOX_TOKEN=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
MétriqueDescription
proxmox.node.*.cpu_pctCPU par node (%)
proxmox.node.*.mem_pctRAM par node (%)
proxmox.node.*.disk_pctDisque par node (%)
proxmox.node.*.vms_runningVMs en marche
proxmox.vm.*.cpu_pctCPU par VM (%)
proxmox.vm.*.mem_pctRAM par VM (%)

VMware vSphere / ESXi

bash
VMWARE_HOST=https://vcenter.example.com
VMWARE_USER=monitoring@vsphere.local
VMWARE_PASSWORD=your_password

Métriques : hosts connectés, VMs on/off, datastores usage. Requiert vSphere 7+ REST API.

XCP-ng / XenServer

bash
XCPNG_HOST=https://xcp.example.com
XCPNG_USER=root
XCPNG_PASSWORD=your_password

Nutanix (Prism)

bash
NUTANIX_HOST=https://prism.example.com:9440
NUTANIX_USER=admin
NUTANIX_PASSWORD=your_password

Métriques : CPU/RAM/storage cluster, VMs on/off, nombre de nodes.

Alertes

Configurez des règles d'alerte sur vos métriques. Les notifications sont envoyées par email dès qu'un seuil est dépassé, avec cooldown configurable pour éviter le spam.

Types de règles disponibles

CatégorieTypeDescription
Logslevel_countTrop d'erreurs d'un niveau donné
Logsmessage_containsMessage contient un mot-clé
Logserror_rateTaux d'erreurs HTTP > seuil
Logstraffic_spikePic de trafic anormal
APMapm_p99_latencyLatence P99 > seuil (ms)
APMapm_apdexScore Apdex (% requêtes rapides)
APMapm_phpfpm_saturationSaturation PHP-FPM
APMapm_crash_loopErreurs 5xx répétées
Infracpu_highCPU > seuil (%)
Inframemory_highRAM > seuil (%)
Infradisk_highDisque > seuil (%)
Infraserver_offlineServeur hors ligne
Cloudcloud_cpu_highCPU EC2 > seuil
Cloudcloud_rds_connectionsConnexions RDS > seuil
Cloudcloud_alb_error_rateErreurs 5xx ALB
Cloudcloud_resource_offlineRessource cloud offline

Canaux de notification

Email, Slack, Discord et Webhook. Configurables dans Dashboard → Alertes → Canaux.

Suggestions automatiques

PulseRadar détecte vos services actifs et suggère des règles d'alerte contextuelles dans Dashboard → Alertes → Suggestions. Par exemple : brute force SSH, erreurs PostgreSQL, saturation PHP-FPM, CPU par serveur. Ajoutez-les en un clic.

Cooldown

Le cooldown (défaut : 30 min) empêche le re-déclenchement d'une alerte pendant cette durée après la première notification.

API d'ingestion

Authentification

Authorization: Bearer <API_KEY>

Endpoints d'ingestion

MéthodeEndpointDescription
POST/v1/logsIngestion logs JSON (single ou batch)
POST/v1/logs/fluent-bitIngestion format Fluent Bit
POST/v1/logs/cloudflareCloudflare Logpush (NDJSON)
POST/v1/logs/drainVercel / Netlify log drain
POST/v1/logs/gelfGELF (Graylog, OVH LDP)
POST/v1/metricsMétriques serveur (agent)
POST/v1/cloud-metricsMétriques cloud (AWS EC2/RDS/ALB)
POST/v1/tracesSpans OTLP JSON
GET/healthStatut du service

Headers optionnels

HeaderDescription
X-Server-IdUUID du serveur (pour lier logs/traces/métriques)
X-Project-IdUUID du projet (si multi-projets)

Limites de débit (rate limiting)

PlanRequêtes / minute
Free60
Starter300
Pro1 000
Business5 000
Scale10 000
EnterpriseIllimité

En cas de dépassement : code HTTP 429 avec header Retry-After: 60.

Lecture des logs (API publique)

bash
GET /v1/logs?project_id=<ID>&level=error&limit=100
Authorization: Bearer <API_KEY>

Clés API

Les clés API sont au niveau du compte (pas du projet). Une seule clé peut ingérer des données pour tous vos projets et serveurs.

Créer une clé

Dashboard → Clés API → Nouvelle clé. Donnez-lui un nom explicite (ex : prod-server-01, laravel-app).

Sécurité

  • La clé n'est affichée qu'une seule fois à la création
  • Stockée en base sous forme de hash SHA-256
  • Révocable instantanément depuis le dashboard
Ne commitez jamais une clé API dans un dépôt Git. Utilisez des variables d'environnement ou un gestionnaire de secrets.

Plans & quotas

Grille tarifaire

PlanEvents/moisRétention logsRétention métriquesPrix
Free200K3 jours7 jours0 €/mois
Starter2M14 jours30 jours19 €/mois
Pro10M30 jours90 jours49 €/mois
Business50M90 jours180 jours99 €/mois
Scale200M180 jours1 an249 €/mois
EnterpriseIllimitéSur mesureSur mesureSur devis

Toutes les fonctionnalités sont incluses dans tous les plans.

Événements facturés vs reçus

Reçus = tous les événements qui arrivent sur l'API d'ingestion.
Facturés = événements écrits dans ClickHouse + forfait métriques.

Forfait métriques

RessourceForfait journalier
Serveur actif (agent installé)1 000 events/jour
Ressource cloud (EC2, RDS, ALB…)500 events/jour

Ce qui n'est jamais facturé

SourceRaison
Métriques serveur (CPU, RAM…)Couvert par le forfait 1 000/jour
Access logs 2xx/3xxTransformés en métriques agrégées
Spans & traces APMInclus gratuitement
Métriques cloudCouvert par le forfait 500/jour
Logs info/debug (si keep_info=false)Droppés avant écriture
Logs floodés (>100/h identiques)Flood protection

Packs supplémentaires

PackEventsPrix
Pack S+2M events9 €
Pack M+10M events19 €
Pack L+50M events39 €

Valables jusqu'à la fin du mois en cours, non reconductibles.

Politique de dépassement

À 80% du quota → alerte email automatique avec estimation du temps restant.
À 100% → l'ingestion continue mais l'accès aux logs est suspendu.
Déblocage immédiat via achat d'un pack ou remise à zéro le 1er du mois.

Les métriques serveur et le dashboard infra restent accessibles même en dépassement de quota.