PHP Luminova: NovaLogger HTTP Remote Logging
Configure encrypted remote logging with a shared secret key and send application logs to a remote server using NovaLogger.
The Luminova\Logger\NovaLogger supports remote HTTP logging, allowing you to send critical logs to a server over the internet.
You can trigger remote logging in three ways:
- Automatically, if remote logging is enabled in your
.envfile. - By calling the
remote()method on theNovaLoggerclass. - By calling the
dispatch()method on theLuminova\Logger\Loggerclass.
Remote logs are sent as an HTTP POST request with a JSON payload, which can be encrypted or unencrypted.
The server receiving the logs must respond quickly and should not block, even if it cannot store the log.
Remote Logging Configuration
To automatically send critical logs to a remote server, set the endpoint in your .env file:
# /.env
logger.remote.logs = https://example.com/api/logs/ingestThis tells NovaLogger where to send your logs whenever a critical event occurs.
Encrypted Log Payload
NovaLogger can send logs encrypted for security. To enable encryption, define a shared secret key in your .env file using logger.remote.shared.key.
If the key is not set, logs will be sent in plain JSON.
# /.env
logger.remote.shared.key = kYixR9E2...Structure of an Encrypted Request
When encryption is enabled, the POST request will look like this:
{
"cipher": "aes-256-gcm",
"iv": "m3J2Tn9n6f9Q",
"tag": "k3SxR9E2...",
"data": "Z0FBQUFBQm..."
}Field Description:
| Field | Type | Description |
|---|---|---|
cipher | string | Encryption algorithm used (currently "aes-256-gcm"). |
iv | string | Base64-encoded Initialization Vector (IV). Required for decryption. |
tag | string | Base64-encoded authentication tag generated by AES-GCM. Ensures the data hasn’t been tampered. |
data | string | Base64-encoded encrypted log payload. Decrypt using the shared key, IV, and tag. |
Notes:
- All four fields are required to decrypt the payload.
- The server must decode
iv,tag, anddatafrom Base64 before callingopenssl_decrypt.- The payload contains the entire log object, not just a single field.
- If decryption fails, the payload should be rejected and logged as invalid.
Log Payload
A raw log is sent as a JSON object with all relevant information about the event. Example:
{
"app": "Luminova",
"host": "api.example.com",
"version": "1.4.2",
"message": "User authentication failed",
"context": {
"user_id": 42,
"role": "admin"
},
"tracer": [...],
"level": "error",
"name": "AppLogger",
"ipaddress": "192.168.1.10",
"url": "https://api.example.com/login",
"referer": "https://example.com",
"method": "POST",
"useragent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)"
}Field Description:
This structure ensures that every log contains enough information to debug, trace, or monitor events effectively.
| Field | Type | Description |
|---|---|---|
app | string | The application name sending the log. |
host | string | The server hostname or domain where the log originated. |
version | string | Application version. |
message | string | A short description of the log event. |
context | object | Additional structured data relevant to the log (e.g., user ID, role). |
level | string | Log severity (error, warning, info, etc.). |
name | string | Logger name or category generating the log. |
ipaddress | string | IP address of the client making the request. |
url | string | Full URL that triggered the log. |
referer | string | The referring URL (if available). |
method | string | HTTP method used for the request (e.g., GET, POST). |
useragent | string | User-Agent string from the client making the request. |
tracer | object[] | PHP Debug tracing details if available |
Remote Server Handling
Key Rules
- Do not crash or throw errors on bad input.
- Do not block the request—log asynchronously if possible.
- Do not call back to the application that sent the log.
- Always return HTTP 200, even if the log cannot be stored (
ok=falsefor failures).
Logging should never interfere with your application.Failures in the logging system must be invisible.
PHP Receivers
The remote server must respond with JSON and HTTP status 200.
- If the response is not JSON or
response.okisfalse, the log will be saved locally.
Endpoint Example:
POST /logs/ingest
Content-Type: application/jsonThis keeps remote logging safe, fast, and non-intrusive.
Encrypted Log Receiver
This example shows how a server can receive encrypted logs from NovaLogger and decrypt them:
// https://example.com/api/logs/ingest.php
// 1. Read the raw JSON payload from the request body
$input = json_decode(file_get_contents('php://input'), true);
// 2. Decrypt the log payload using AES-GCM
$plaintext = openssl_decrypt(
base64_decode($input['data']), // Ciphertext
$input['cipher'] ?? 'aes-256-gcm', // Encryption algorithm
LOG_SHARED_SECRET, // Shared secret key
OPENSSL_RAW_DATA, // Raw binary output
base64_decode($input['iv']), // Initialization vector
base64_decode($input['tag']) // Authentication tag
);
// 3. Handle decryption failure
if ($plaintext === false) {
echo json_encode([
'ok' => false,
'description' => 'Invalid encrypted payload' // Inform client of failure
]);
exit;
}
// 4. Decode the decrypted JSON log
$log = json_decode($plaintext, true);
// 5. Store the log as needed (database, file, queue, etc.)
// 6. Return success
echo json_encode(['ok' => true]);Notes:
- Always verify the IV, tag, and ciphertext are present before attempting decryption.
- Always validate the decrypted payload before storing.
- Respond with
ok=falseon any failure—never crash.
Raw Log Receiver
This example shows how to receive plain JSON logs:
// https://example.com/api/logs/ingest.php
// 1. Read the raw JSON payload
$data = json_decode(file_get_contents('php://input'), true);
// 2. Validate the payload
if (!is_array($data) || empty($data['message'])) {
echo json_encode([
'ok' => false,
'description' => 'Invalid log payload' // Inform client if payload is bad
]);
exit;
}
// 3. Store the log as needed (database, file, queue, etc.)
// 4. Return success
echo json_encode(['ok' => true]);Notes:
- The server must always return HTTP 200, even on failure.
- Invalid payloads are stored locally if necessary.
Success Response
A response is successful if ok is set to true.
{
"ok": true
}Failure Response
A response is unsuccessful if either ok is set to false.You can optionally include description to explain why the log failed. The client will record this locally, even if no reason is provided.
{
"ok": false,
"description": "Invalid payload"
}Notes:
- Response fields are for diagnostics only.
- Always return HTTP 200, regardless of success or failure.
Response Context
When remote logging fails, the server can return additional context.This context will be stored locally along with the log, making debugging easier.
Example:
{
"ok": false,
"context": {
"timestamp": "2026-01-14T03:00:00Z",
"log_id": "abc123xyz",
// ...
}
}| Field | Description |
|---|---|
log_id | A unique ID assigned to each log. Useful for tracing and debugging specific logs. |
timestamp | The time the server processed the log. Helps correlate logs between client and server. |
Including this context is optional but highly recommended for troubleshooting remote logging issues.