skip to content

Which Appium server flags decide where the server's own log goes and how much it carries?

level: seniorimportance: should knowfreq 46%

answer

  1. process-level, not per-session
  2. verbosity, destination, timestamp
  3. -g is the short form
  4. one stream carries both platforms

basics

~20 s

The Appium server's own log is shaped by server flags: --log-level sets verbosity, --log sends the stream to a file, and --log-timestamp prefixes each line. That one stream carries every session the process handles, Android and Apple alike.

solid answer

~40 s

`--log-level` sets how much the server prints, `--log` (short form `-g`) sends the stream to a file as well as the console, and `--log-timestamp` prefixes every line with a timestamp so entries line up against a test's own clock. The same server schema also carries `--log-format`, `--log-filters`, `--log-no-colors`, `--debug-log-spacing`, `--long-stacktrace` and `--trace-dir`. The important property is scope: these are **server-process** settings chosen when you start `appium`, not capabilities on a session. They therefore apply uniformly to every session that process handles — the Android ones and the Apple ones — which is the deliberate contrast with device logs, whose bucket names differ per platform.

go deeper

for a junior

Know that the Appium server writes its own log, separate from the device's log, and that flags on the appium command decide how loud it is and whether it lands in a file.

for a middle

Be ready to name --log-level, --log and --log-timestamp and say what each does. Explain why they are process-level settings and what that means for a server handling both Android and Apple sessions.

for a senior

Show that you capture the stream to a file with timestamps before you need it, and that you know the server log answers a different question from a device log. Be able to justify your verbosity choice.

for a principal

Own the shape of log capture across the fleet: how many server processes, one file per lane or one shared, what verbosity is worth its volume, and how the stream stays correlatable to a run.

## Two different logs, and only one of them is yours to configure An Appium run produces two quite different streams, and conflating them is the usual source of confusion. The first is the **server's own log**: the output the `appium` process writes as it accepts a session, routes each command, calls into a driver and hears back. It is Appium narrating itself, and it is entirely under your control through server flags. The second is the **device log**, which is the platform's own output — pulled out of a session through `POST /session/:sessionId/se/log` under a per-driver type name. You do not configure its verbosity with a server flag; it is the device's log, not Appium's. | | the server's own log | a device log | |---|---|---| | produced by | the `appium` process | the device or its platform | | configured by | server flags at startup | not by server flags | | scope | every session that process handles | one session, one named type | | same on Android and Apple? | yes, one stream for both | no, the type names diverge | ## The three flags this leaf turns on - **`--log-level`** sets how verbose the server's stream is. It is the dial between a stream you can read at a glance and one that shows every command and response. - **`--log`** (short form `-g`) sends the stream to a file in addition to the console. Without it there is nothing to attach to a failure once the terminal scrolls away or the process is running under a supervisor. - **`--log-timestamp`** prefixes each line with a timestamp. This is what lets you take the moment your test recorded a failure and find the command the server was serving at that instant. The last of those is worth dwelling on. A server log without timestamps is readable but not *correlatable*: you can see what happened, not when, and lining it up against a test report or a device log becomes guesswork. ## The rest of the logging surface Appium's server configuration schema carries a wider set of logging flags than the three above. The ones worth knowing they exist: - `--log-format` — an additional shape control on the emitted stream. - `--log-filters` — a filtering hook applied to the stream. - `--log-no-colors` — drops the ANSI colouring, which is what you want for a file you are going to grep or ship to another tool. - `--debug-log-spacing` — an additional readability control. - `--long-stacktrace` — keeps deeper error traces rather than trimmed ones. - `--trace-dir` and `--webhook` — further destinations in the same schema. The practical rule is to name a flag only from the server's own schema. Client libraries have historically shipped enums of server flags that have not existed for years; a flag that appears in a client's helper class is not evidence that this server accepts it. ## One stream, two platforms Because these are process-level settings, they cut across the platform divide rather than along it. Start one `appium` process with `--log-level` turned up and `--log` pointed at a file, and that file will carry the UiAutomator2 or Espresso session driving your caving trip-log app on Android **and** the XCUITest session driving it on an iPhone, interleaved, in the same format, with the same timestamps. That is genuinely useful and it is also the thing to watch: - Interleaving means a single file mixes lanes. Sessions are distinguished by their ids in the stream, so an id is what you grep for, not a platform name. - If you run one server process per device, you get one file per lane for free — at the cost of remembering that `--log` names a file and two processes must not name the same one. - Verbosity is not free. Turning `--log-level` up for a whole fleet produces a great deal of output whose value is concentrated in the few runs that failed. ## Operating it in the caving trip-log suite When a caving trip-log run fails at the step that saves a survey leg, the server log is the first place to look, on either platform, and it answers a specific question: *what did the client ask for, and what did the driver say back?* It shows the command in flight, its parameters and the error the driver returned. What it does not show is what the app itself was doing inside the device — that is the device log's job, and its bucket name depends on the platform. So the honest division of labour is: 1. Server log, shaped by `--log-level` and captured with `--log`: the automation side of the failure. 2. Device log, pulled per session under a platform-specific type name: the application side of it. 3. `--log-timestamp` on the first so the two can be laid against each other at all. Get that division right and each stream stays small enough to read. Get it wrong and you either have a verbose server log that never explains why the app misbehaved, or a device log with no record of which command provoked it.

  • Why is --log-level not something you set per session through a capability?
    Because it configures the `appium` process, not a driver session. The process is already running and already logging before any session request arrives, so verbosity has to be decided at startup. The consequence is that every session that process handles inherits the same setting — one reason teams run a server process per device lane rather than one shared server.
  • Two Appium processes on one host both point --log at the same file. What goes wrong?
    You get one file with two servers' streams interleaved, and no flag separates them again. Session ids still let you pick a run apart by hand, but the simplicity of one-file-per-lane is gone. Give each process its own `--log` path; that is normally cheaper than reconstructing which process wrote which line.

saying these in an interview costs you the question

  • Thinks --log-level is a session capability rather than a server flag
  • Expects --log-level to change what a device log bucket contains
  • Names server flags from a client library's enum instead of the server schema
  • Runs a fleet at maximum verbosity and keeps nothing to a file
  • Assumes the server log is written per platform lane automatically