PlanyDocs
API reference

LogService

api.plany.cloud:443Regional2 methods

Read back what a game server or a sandbox printed. Every line a game server logs, and every line a sandbox's container writes, is kept and searchable by time and by text. ListLogLines reads one server's or one sandbox's output, newest first by default; ListAgentRuns shows each time it started, so you can see exactly what happened either side of a restart.

ListLogLines

Read
plany.gamelog.v1.LogService/ListLogLines

Returns the lines one game server, or one sandbox, logged.

Newest first, which is the opposite of how a log reads and the right default for how one is opened: the first question is almost always "what just happened", and a chronological first page of a server that has been up for a week is a week old. Ask for ORDER_OLDEST_FIRST to read forwards.

Parameters

  • parentstringRequired

    projects/{project}/locations/{location}/gameServers/{game_server}, or projects/{project}/locations/{location}/sandboxes/{sandbox}.

    One server, or one sandbox across all of its instances. There is deliberately no wildcard: this is the highest-volume data on the platform, and projects/- over it is a query that would answer slowly, hold a connection open and tell nobody anything they asked.

  • page_sizeint32
  • page_tokenstring
  • agent_run_idstring

    Restrict to one boot of the agent. See ListAgentRuns.

  • streamStream

    Restrict to one stream. Unset returns all three, interleaved, which is how they are worth reading — "the server died" and "the agent asked it to" are far easier to correlate in one stream than in two.

    STREAM_STDOUTSTREAM_STDERRSTREAM_AGENT
  • time_rangeInterval

    Restrict by observation time — when the server printed the line, not when Plany received it. Lines a server buffered while it could not reach Plany are placed at the time they happened.

  • containsstring

    Restrict to lines containing this substring, case-insensitively. A plain substring, not a regular expression.

  • ORDER_NEWEST_FIRSTORDER_OLDEST_FIRST

Returns

ListLogLinesResponse.

grpcurl -H "authorization: Bearer $PLANY_API_KEY" \
-d '{
"parent": "projects//locations//gameServers/",
"page_size": 50
}' \
api.plany.cloud:443 plany.gamelog.v1.LogService/ListLogLines
Example response
{
"records": [
{
"game_server": "projects//locations//gameServers/",
"agent_run_id": "my-agent-run",
"line": {
"observe_time": "2026-10-04T12:00:00Z",
"stream": "STREAM_STDOUT",
"text": "",
"sequence": "0"
},
"ingest_time": "2026-10-04T12:00:00Z",
"sandbox": "projects//locations//sandboxes/"
}
],
"next_page_token": "",
"gaps": [
{
"agent_run_id": "my-agent-run",
"report_time": "2026-10-04T12:00:00Z",
"dropped_lines": "0"
}
]
}

ListAgentRuns

Read
plany.gamelog.v1.LogService/ListAgentRuns

Returns each run that shipped lines for a server or a sandbox.

A run is one start. For a sandbox, a run belongs to one instance and its id begins with the instance id — so this is also "which instances have run, and when".

Line sequence numbers restart at 1 on every start, so two lines either side of a restart are ordered by the run they belong to. This is what turns a wall of lines into "the four times this server has started".

Parameters

  • parentstringRequired

    A game server or a sandbox, exactly as ListLogLinesRequest.parent.

  • page_sizeint32
  • page_tokenstring

Returns

ListAgentRunsResponse.

grpcurl -H "authorization: Bearer $PLANY_API_KEY" \
-d '{
"parent": "projects//locations//gameServers/",
"page_size": 50
}' \
api.plany.cloud:443 plany.gamelog.v1.LogService/ListAgentRuns
Example response
{
"agent_runs": [
{
"agent_run_id": "my-agent-run",
"first_line_time": "2026-10-04T12:00:00Z",
"last_line_time": "2026-10-04T12:00:00Z",
"line_count": "0",
"dropped_lines": "0"
}
],
"next_page_token": ""
}

The AgentRun object

AgentRun is one start of a server or sandbox instance, as seen from the lines it shipped.

Worked out from the lines themselves rather than reported. A run that is still going has a last_line_time that keeps moving.

Attributes

  • agent_run_idstring
  • first_line_timeTimestamp
  • last_line_timeTimestamp
  • line_countint64
  • dropped_linesint64

    Lines this run is known to have dropped. Zero means none were reported, which is not quite the same as none being lost — an agent killed outright never gets to admit to its last batch.

AgentRun
{
"agent_run_id": "my-agent-run",
"first_line_time": "2026-10-04T12:00:00Z",
"last_line_time": "2026-10-04T12:00:00Z",
"line_count": "0",
"dropped_lines": "0"
}

The LogGap object

LogGap is a stretch of lines the agent threw away rather than block the game.

Reported rather than hidden, and surfaced beside the lines rather than in a metric. A gap in a log is invisible in the data: a session that appears to last four hours because the disconnect fell in the gap is indistinguishable from a real one, so a reader who cannot see the gap has no way to distrust what surrounds it.

Attributes

  • agent_run_idstring
  • report_timeTimestamp

    When the agent admitted to the loss, which is the batch after the lines went missing. The lines themselves have no time — they were never sent.

  • dropped_linesint64
LogGap
{
"agent_run_id": "my-agent-run",
"report_time": "2026-10-04T12:00:00Z",
"dropped_lines": "0"
}

The LogRecord object

LogRecord is one stored line and what is known about how it arrived.

Attributes

  • game_serverstring

    projects/{project}/locations/{location}/gameServers/{game_server}. Empty for a sandbox's line, which sets sandbox instead.

  • agent_run_idstring

    The agent run that shipped it. Sequence numbers restart at 1 when the agent does, so (agent_run_id, line.sequence) is what actually orders two lines across a restart.

  • Show child attributes
    • observe_timeTimestampRequired

      When the server printed the line. Not when Plany received it: a server that could not reach Plany for ten minutes buffers its lines, and they keep their original times.

    • textstringRequired

      The line, verbatim and without its trailing newline.

      Verbatim matters: a template is a regular expression over exactly these bytes, so any normalisation here would silently invalidate every template learned before it was introduced.

    • streamStream

      Which stream it came from.

      Kept distinct because a game server that logs everything to stderr is common, and collapsing the two loses the only signal that something was actually wrong.

      STREAM_STDOUTSTREAM_STDERRSTREAM_AGENT
    • sequenceint64

      Monotonic sequence within one agent run, starting at 1.

      Two lines can share a timestamp — most servers log to the second — and ordering between a connect and the disconnect that follows it is the whole point. This is what breaks that tie.

  • ingest_timeTimestamp

    When Plany received the line, as distinct from when the server printed it.

    A large gap between the two means the server was buffering — for example, because it could not reach Plany for a while.

  • sandboxstring

    projects/{project}/locations/{location}/sandboxes/{sandbox}, for a line a sandbox's container printed. Exactly one of this and game_server is set.

LogRecord
{
"game_server": "projects//locations//gameServers/",
"agent_run_id": "my-agent-run",
"line": {
"observe_time": "2026-10-04T12:00:00Z",
"stream": "STREAM_STDOUT",
"text": "",
"sequence": "0"
},
"ingest_time": "2026-10-04T12:00:00Z",
"sandbox": "projects//locations//sandboxes/"
}

ListAgentRunsResponse

  • Most recent first.

    Show child attributes
    • agent_run_idstring
    • first_line_timeTimestamp
    • last_line_timeTimestamp
    • line_countint64
    • dropped_linesint64

      Lines this run is known to have dropped. Zero means none were reported, which is not quite the same as none being lost — an agent killed outright never gets to admit to its last batch.

  • next_page_tokenstring

ListLogLinesResponse

  • Show child attributes
    • game_serverstring

      projects/{project}/locations/{location}/gameServers/{game_server}. Empty for a sandbox's line, which sets sandbox instead.

    • agent_run_idstring

      The agent run that shipped it. Sequence numbers restart at 1 when the agent does, so (agent_run_id, line.sequence) is what actually orders two lines across a restart.

    • Show child attributes
      • observe_timeTimestampRequired

        When the server printed the line. Not when Plany received it: a server that could not reach Plany for ten minutes buffers its lines, and they keep their original times.

      • textstringRequired

        The line, verbatim and without its trailing newline.

        Verbatim matters: a template is a regular expression over exactly these bytes, so any normalisation here would silently invalidate every template learned before it was introduced.

      • streamStream

        Which stream it came from.

        Kept distinct because a game server that logs everything to stderr is common, and collapsing the two loses the only signal that something was actually wrong.

        STREAM_STDOUTSTREAM_STDERRSTREAM_AGENT
      • sequenceint64

        Monotonic sequence within one agent run, starting at 1.

        Two lines can share a timestamp — most servers log to the second — and ordering between a connect and the disconnect that follows it is the whole point. This is what breaks that tie.

    • ingest_timeTimestamp

      When Plany received the line, as distinct from when the server printed it.

      A large gap between the two means the server was buffering — for example, because it could not reach Plany for a while.

    • sandboxstring

      projects/{project}/locations/{location}/sandboxes/{sandbox}, for a line a sandbox's container printed. Exactly one of this and game_server is set.

  • next_page_tokenstring
  • Gaps overlapping the window these records came from.

    Returned with the lines rather than behind another call, because a caller who has to ask separately is a caller who will not, and a gap that is not shown beside the lines might as well not be recorded.

    Show child attributes
    • agent_run_idstring
    • report_timeTimestamp

      When the agent admitted to the loss, which is the batch after the lines went missing. The lines themselves have no time — they were never sent.

    • dropped_linesint64

Enums

ListLogLinesRequest.Order

Order results are returned in.

ValueDescription
ORDER_UNSPECIFIEDNewest first.
ORDER_NEWEST_FIRSTNewest first. The default, because a log is usually opened to find out what just happened.
ORDER_OLDEST_FIRSTOldest first — reading a boot forwards from the start.