CKEditor AI On-Premises logs
CKEditor AI On-Premises writes JSON log lines to stdout and stderr. Each line carries a level, and each request can also write a summary line with a trace identifier, a duration, and a status code. Use these lines to see the request rate, to alert on errors, and to find the one request that failed.
In production, ship the container output to a distributed logging system such as ELK or CloudWatch. This article shows how. For traces, token usage, and AI-specific dashboards, see Observability.
Every log line carries a level property. By default, CKEditor AI On-Premises writes only the lines at level 40 and above. To see more, set the LOG_LEVEL environment variable to the lowest level you want.
Keep LOG_LEVEL at 40 or above in production. Levels below 40 produce a large volume of lines, and that volume can cause performance or memory problems.
The six levels:
10– Trace. The most detailed information about the processes in the application.20– Debug. A line added temporarily, to monitor a case that is hard to debug.30– Info. A change to a resource, or an audit log line.40– Warn. A side effect of asynchronous event processing, a process that failed once and then succeeded on a retry, or a minor problem with the behavior of a model. A warning next to an error at level50or above gives you context for debugging.50– Error. A process stopped unexpectedly, or it does not work correctly.60– Fatal. An error that stops the whole application.
A warning about the behavior of a model usually reports a tool that was called with invalid input. CKEditor AI On-Premises returns the error to the model, and the model corrects itself. A small, steady number of these warnings is normal.
Set the ENABLE_METRIC_LOGS=true environment variable to log a summary of every request. Use the summaries to track request rates, latency, and errors.
Each summary carries the Request summary message and the metrics tag, so you can search for either one to isolate them. CKEditor AI On-Premises writes a summary for every client-facing request, but not for a health check.
Summaries are always written at level=30, even when the request ends with an error. They appear whenever ENABLE_METRIC_LOGS=true, whatever LOG_LEVEL is set to. Because the level never changes, filter on data.status and data.statusCode to find the failures.
Statuses:
success– The response status code is below400.warning– The response status code is400or higher, but below500.fail– The response status code is500or higher.
Each request summary contains the following information:
handler– the name of the API operation that served the request, for examplegetAiModels.traceId– a unique identifier of the request. Search for it to find every log line about the same request.tags– a semicolon-separated list of tags.data– an object holding the fields below.data.duration– the request duration in milliseconds.data.transport– the request transport. CKEditor AI On-Premises serves HTTP requests only, so this is alwayshttp.data.status– the request status, one of the three statuses above.data.statusCode– the HTTP status code of the response.data.environmentId– the environment the request was made for. The value isunknownwhen the request failed before CKEditor AI On-Premises resolved the environment.data.url– the request URL, including the query string.data.method– the request method.
When a request ends with an error, the summary also contains data.message with the error message.
An example request summary:
{
"level": 30,
"time": "2026-01-01T00:00:00.000Z",
"msg": "Request summary",
"handler": "getAiModels",
"traceId": "mhs3p3wb1fe2a10c67asd098e846753g4",
"data": {
"duration": 7,
"transport": "http",
"statusCode": 200,
"environmentId": "mk3uKGKsWjbW109o0W2D",
"status": "success",
"url": "/v1/models/1?languageCode=en",
"method": "GET"
},
"tags": "metrics"
}Copy codeThe Collaboration Server documentation shows example charts built from this log structure. The latency chart, the error count chart, and the warning count chart work here without any change. Skip the chart that splits requests by transport, because CKEditor AI On-Premises serves HTTP only.
Docker captures the container output with a log driver. The default driver writes the output to files.
With this driver, run docker logs to show the output of a container. Add the -f flag to follow the output in real time. See the official Docker documentation for the full logs reference.
The output of a container that runs for a long time can fill the disk. Set the max-size option to rotate the log files.
With more than one instance of CKEditor AI On-Premises, send the container output to a distributed logging system, so that you search all instances at once.
Your cloud provider’s own service is the shortest path when you already run in that cloud:
- AWS – CloudWatch
- Google Cloud – Cloud Logging
- Azure – Azure Monitor
To use CloudWatch with AWS ECS, create a log group and set the log driver to awslogs. ECS then streams the logs to CloudWatch.
The logConfiguration may look like this:
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-region": "us-west-2",
"awslogs-group": "cksource",
"awslogs-stream-prefix": "ck-ai-service-logs"
}
}Copy codeSee Using the awslogs Log Driver for the driver options.
On your own infrastructure, or when you cannot use your provider’s service, run a logging system yourself. Common choices:
-
ELK + Filebeat
Filebeat ships the logs from Docker, Elasticsearch stores them, and Kibana displays them. You do not need Logstash, because the logs are already structured. -
Fluentd
A dedicated Docker log driver sends the logs. Fluentd has its own frontend, and it can also feed Elasticsearch and Kibana for better filtering. -
Graylog
A dedicated Docker log driver sends the logs. Graylog has its own frontend, stores the logs in Elasticsearch, and keeps its configuration in MongoDB.
This example runs Fluentd, Elasticsearch, and Kibana under Docker Compose, then starts CKEditor AI On-Premises with the Fluentd log driver. At the end, you read the logs in Kibana. Start the logging services before CKEditor AI On-Premises.
First, define the fluentd, elasticsearch, and kibana services in docker-compose.yml:
version: '3.7'
services:
fluentd:
build: ./fluentd
volumes:
- ./fluentd/fluent.conf:/fluentd/etc/fluent.conf
ports:
- "24224:24224"
- "24224:24224/udp"
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:6.8.5
expose:
- 9200
ports:
- "9200:9200"
kibana:
image: docker.elastic.co/kibana/kibana:6.8.5
environment:
ELASTICSEARCH_HOSTS: "http://elasticsearch:9200"
ports:
- "5601:5601"Copy codeFluentd needs fluent-plugin-elasticsearch to write to Elasticsearch. Build the Fluentd image from a fluentd/Dockerfile that installs the plugin:
FROM fluent/fluentd:v1.10-1
USER root
RUN apk add --no-cache --update build-base ruby-dev \
&& gem install fluent-plugin-elasticsearch \
&& gem sources --clear-all
Copy codeNext, configure the input server and the Elasticsearch connection in fluentd/fluent.conf:
<source>
@type forward
port 24224
bind 0.0.0.0
</source>
<match *.**>
@type copy
<store>
@type elasticsearch
host elasticsearch
port 9200
logstash_format true
logstash_prefix fluentd
logstash_dateformat %Y%m%d
include_tag_key true
type_name access_log
tag_key @log_name
flush_interval 1s
</store>
<store>
@type stdout
</store>
</match>Copy codeRun the services:
docker-compose up --buildCopy codeWhen the services are up, start CKEditor AI On-Premises with the Fluentd log driver:
docker run --init -p 8000:8000 \
--log-driver=fluentd \
--log-opt fluentd-address=[Fluentd address]:24224 \
[Your config here] \
docker.cke-cs.com/ai-service:[version]Copy codeOpen Kibana at http://localhost:5601/. On the first run, Kibana asks you to create an index. Enter the pattern fluentd-* and click Create. Your logs then appear in the Discover tab.