Transaction API

edit

The APM Server exposes an API Endpoint to send transaction records. Unless you are implementing an agent, you don’t need to know about the specifics of this API.

To send transaction records you need to send a HTTP POST request to APM Server transactions endpoint. Information pertaining to the record must be sent as a JSON object to the endpoint.

Find more information about:

Schema Definition

edit

The APM Server uses a JSON Schema for validating the transaction requests. Find details on how the schema is defined:

Payload

edit
{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "$id": "docs/spec/transactions/wrapper.json",
    "title": "Transactions Wrapper",
    "description": "List of transactions wrapped in an object containing some other attributes normalized away form the transactions themselves",
    "type": "object",
    "properties": {
        "app": {
            "$ref": "../app.json"
        },
        "system": {
            "$ref": "../system.json"
        },
        "transactions": {
            "type": "array",
            "items": {
                "$ref": "transaction.json"
            },
            "minItems": 1
        }
    },
    "required": ["app", "transactions"]
}

Transaction

edit
{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "$id": "docs/spec/transactions/transaction.json",
    "type": "object",
    "description": "Data captured by an agent representing an event occurring in a monitored app",
    "properties": {
        "context": {
            "$ref": "../context.json"
        },
        "duration": {
            "type": "number",
            "description": "How long the transaction took to complete, in ms with 3 decimal points"
        },
        "id": {
            "type": "string",
            "description": "UUID for the transaction, referred by its traces",
            "pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$"
        },
        "name": {
            "type": "string",
            "description": "Generic designation of a transaction in the scope of a single app (eg: 'GET /users/:id')",
            "maxLength": 1024
        },
        "result": {
          	"type": "string",
          	"description": "The result of the transaction. HTTP status code for HTTP-related transactions.",
            "maxLength": 1024
        },
        "timestamp": {
            "type": "string",
            "pattern": "Z$",
            "format": "date-time",
            "description": "Recorded time of the transaction, UTC based and formatted as YYYY-MM-DDTHH:mm:ss.sssZ"
        },
        "traces": {
            "type": ["array", "null"],
            "items": {
                "$ref": "trace.json"
            },
            "minItems": 0
        },
        "type": {
            "type": "string",
            "description": "Keyword of specific relevance in the app's domain (eg: 'request', 'cache', etc)",
            "maxLength": 1024
        }
    },
    "required": ["id", "name", "duration", "type", "timestamp"]
}

Trace

edit
{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "$id": "docs/spec/transactions/trace.json",
    "type": "object",
    "properties": {
        "id": {
            "type": ["number", "null"],
            "description": "The locally unique ID of the trace."
        },
        "context": {
            "type": ["object", "null"],
            "description": "Any other arbitrary data captured by the agent, optionally provided by the user",
            "properties": {
                "db": {
                    "type": ["object", "null"],
                    "description": "An object containing contextual data for database traces",
                    "properties": {
                        "instance": {
                           "type": ["string", "null"],
                           "description": "Database instance name"
                        },
                        "statement": {
                           "type": ["string", "null"],
                           "description": "A database statement (e.g. query) for the given database type"
                        },
                        "type": {
                           "type": ["string", "null"],
                           "description": "Database type. For any SQL database, \"sql\". For others, the lower-case database category, e.g. \"cassandra\", \"hbase\", or \"redis\""
                        },
                        "user": {
                           "type": ["string", "null"],
                           "description": "Username for accessing database"
                        }
                    }
                }
            }
        },
        "duration": {
            "type": "number",
            "description": "Duration of the trace in milliseconds"
        },
        "name": {
            "type": "string",
            "description": "Generic designation of a trace in the scope of a transaction",
            "maxLength": 1024
        },
        "parent": {
            "type": ["number", "null"],
            "description": "The locally unique ID of the parent of the trace."
        },
        "stacktrace": {
            "type": ["array", "null"],
            "description": "List of stack frames with variable attributes (eg: lineno, filename, etc)",
            "items": {
                "$ref": "../stacktrace_frame.json"
            },
            "minItems": 0
        },
        "start": {
            "type": "number",
            "description": "Offset relative to the transaction's timestamp identifying the start of the trace, in milliseconds"
        },
        "type": {
            "type": "string",
            "description": "Keyword of specific relevance in the app's domain (eg: 'db.postgresql.query', 'template.erb', etc)",
            "maxLength": 1024
        }
    },
    "dependencies": {
        "parent": {
            "required": ["id"]
        }
    },
    "required": ["duration", "name", "start", "type"]
}

App

edit
{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "$id": "doc/spec/app.json",
    "title": "App",
    "type": "object",
    "allOf": [
        {"$ref": "app_core.json"},
        {"properties": {
            "agent": {
                "type": "object",
                "properties": {
                    "name": {
                        "type": "string",
                        "maxLength": 1024
                    },
                    "version": {
                        "type": "string",
                        "maxLength": 1024
                    }
                },
                "required": [
                    "name",
                    "version"
                ]
            },
            "argv": {
                "type": [
                    "array",
                    "null"
                ],
                "minItems": 0
            },
            "framework": {
                "type": [
                    "object",
                    "null"
                ],
                "properties": {
                    "name": {
                        "type": "string",
                        "maxLength": 1024
                    },
                    "version": {
                        "type": "string",
                        "maxLength": 1024
                    }
                },
                "required": [
                    "name",
                    "version"
                ]
            },
            "language": {
                "type": [
                    "object",
                    "null"
                ],
                "properties": {
                    "name": {
                        "type": "string",
                        "maxLength": 1024
                    },
                    "version": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "maxLength": 1024
                    }
                },
                "required": [
                    "name"
                ]
            },
            "pid": {
                "type": [
                    "number",
                    "null"
                ]
            },
            "process_title": {
                "type": [
                    "string",
                    "null"
                ],
                "maxLength": 1024
            },
            "runtime": {
                "type": [
                    "object",
                    "null"
                ],
                "properties": {
                    "name": {
                        "type": "string",
                        "maxLength": 1024
                    },
                    "version": {
                        "type": "string",
                        "maxLength": 1024
                    }
                },
                "required": [
                    "name",
                    "version"
                ]
            }
        },
        "required": ["agent"]
        }
    ]
}

System

edit
{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "$id": "doc/spec/system.json",
    "title": "System",
    "type": ["object", "null"],
    "properties": {
        "architecture": {
            "description": "Architecture of the system the agent is running on.",
            "type": ["string", "null"],
            "maxLength": 1024
        },
        "hostname": {
            "description": "Hostname of the system the agent is running on.",
            "type": ["string", "null"],
            "maxLength": 1024
        },
        "platform": {
            "description": "Name of the system platform the agent is running on.",
            "type": ["string", "null"],
            "maxLength": 1024
        }
    }
}

Context

edit
{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "$id": "doc/spec/context.json",
    "title": "Context",
    "description": "Any arbitrary contextual information regarding the event, captured by the agent, optionally provided by the user",
    "type": ["object", "null"],
    "properties": {
        "custom": {
            "description": "An arbitrary mapping of additional metadata to store with the event.",
            "type": ["object", "null"],
            "regexProperties": true,
            "patternProperties": {
                "^[^.*\"]*$": {}
            },
            "additionalProperties": false
        },
        "response": {
            "type": ["object", "null"],
            "properties": {
                "finished": {
                    "type": ["boolean", "null"]
                },
                "headers": {
                    "type": ["object", "null"],
                    "properties": {
                        "content-type": {
                            "type": ["string", "null"]
                        }
                    }
                },
                "headers_sent": {
                    "type": ["boolean", "null"]
                },
                "status_code": {
                    "type": ["number", "null"]
                }
            }
        },
        "request": {
            "$ref": "request.json"
        },
        "tags": {
            "type": ["object", "null"],
            "regexProperties": true,
            "patternProperties": {
                "^[^.*\"]*$": {
                    "type": "string",
                    "maxLength": 1024
                }
            },
            "additionalProperties": false
        },
        "user": {
            "$ref": "user.json"
        }
    }
}

Stacktrace Frame

edit
{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "$id": "docs/spec/stacktrace.json",
    "title": "Stacktrace",
    "type": "object",
    "description": "A stacktrace frame, contains various bits (most optional) describing the context of the frame",
    "properties": {
        "abs_path": {
            "description": "The absolute path of the file involved in the stack frame",
            "type": ["string", "null"]
        },
        "colno": {
            "description": "Column number",
            "type": ["number", "null"]
        },
        "context_line": {
            "description": "The line of code part of the stack frame",
            "type": ["string", "null"]
        },
        "filename": {
            "description": "The relative filename of the code involved in the stack frame, used e.g. to do error checksumming",
            "type": "string"
        },
        "function": {
            "description": "The function involved in the stack frame",
            "type": ["string", "null"]
        },
        "in_app": {
            "type": ["boolean", "null"]
        },
        "lineno": {
            "description": "The line number of code part of the stack frame, used e.g. to do error checksumming",
            "type": "number"
        },
        "module": {
            "description": "The module to which frame belongs to",
            "type": ["string", "null"]
        },
        "post_context": {
            "description": "The lines of code after the stack frame",
            "type": ["array", "null"],
            "minItems": 0
        },
        "pre_context": {
            "description": "The lines of code before the stack frame",
             "type": ["array", "null"],
            "minItems": 0
        },
        "vars": {
            "description": "Local variables for this stack frame",
            "type": ["object", "null"],
            "properties": {}
        }
    },
    "required": ["filename", "lineno"]
}

Request

edit
{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "$id": "docs/spec/http.json",
    "title": "Request",
    "description": "If a log record was generated as a result of a http request, the http interface can be used to collect this information.",
    "type": ["object", "null"],
    "properties": {
        "body": {
            "description": "Data should only contain the request body (not the query string). It can either be a dictionary (for standard HTTP requests) or a raw request body.",
            "type": ["object", "string", "null"]
        },
        "env": {
            "description": "The env variable is a compounded of environment information passed from the webserver.",
            "type": ["object", "null"],
            "properties": {}
        },
        "headers": {
            "description": "Should include any headers sent by the requester. Cookies will be taken by headers if supplied.",
            "type": ["object", "null"],
            "properties": {
                "content-type": {
                    "type": ["string", "null"]
                },
                "cookie": {
                    "description": "Cookies sent with the request. It is expected to have values delimited by semicolons.",
                    "type": ["string", "null"]
                },
                "user-agent": {
                    "type": ["string", "null"]
                }
            }
        },
        "http_version": {
            "description": "HTTP version.",
            "type": ["string", "null"],
            "maxLength": 1024
        },
        "method": {
            "description": "HTTP method.",
            "type": "string",
            "maxLength": 1024
        },
        "socket": {
            "type": ["object", "null"],
            "properties": {
                "encrypted": {
                    "description": "Indicates whether request was sent as SSL/HTTPS request.",
                    "type": ["boolean", "null"]
                },
                "remote_address": {
                    "type": ["string", "null"]
                }
            }
        },
        "url": {
            "description": "A complete Url, with scheme, host and path.",
            "type": "object",
            "properties": {
                "raw": {
                    "type": ["string", "null"],
                    "maxLength": 1024
                },
                "protocol": {
                    "type": ["string", "null"],
                    "maxLength": 1024
                },
                "hostname": {
                    "type": ["string", "null"],
                    "maxLength": 1024
                },
                "port": {
                    "type": ["string", "null"],
                    "maxLength": 1024
                },
                "pathname": {
                    "type": ["string", "null"],
                    "maxLength": 1024
                },
                "search": {
                    "description": "The search describes the query string of the request. It is expected to have values delimited by ampersands.",
                    "type": ["string", "null"],
                    "maxLength": 1024
                },
                "hash": {
                    "type": ["string", "null"],
                    "maxLength": 1024
                }
            }
        },
        "cookies": {
            "description": "A parsed key-value object of cookies",
            "type": ["object", "null"]
        }
    },
    "required": ["url", "method"]
}

User

edit
{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "$id": "docs/spec/user.json",
    "title": "User",
    "description": "Describes the authenticated User for a request.",
    "type": ["object", "null"],
    "properties": {
        "id": {
            "type": ["string", "number", "null"],
            "maxLength": 1024
        },
        "email": {
            "type": ["string", "null"],
            "maxLength": 1024
        },
        "username": {
            "type": ["string", "null"],
            "maxLength": 1024
        }
    }
}

Examples

edit

Send an example request to the APM Server:

curl http://localhost:8200/v1/transactions \
  --header "Content-Type: application/json" \
  --data @docs/data/intake-api/generated/transaction/payload.json

See examples on how a transaction request to the APM Server can look like:

Payload with several Transactions

edit
{
    "app": {
        "name": "1234_app-12a3",
        "version": "5.1.3",
        "pid": 1234,
        "process_title": "node",
        "argv": [
            "node",
            "server.js"
        ],
        "language": {
            "name": "ecmascript",
            "version": "8"
        },
        "runtime": {
            "name": "node",
            "version": "8.0.0"
        },
        "framework": {
            "name": "Express",
            "version": "1.2.3"
        },
        "agent": {
            "name": "elastic-node",
            "version": "3.14.0"
        }
    },
    "system": {
        "hostname": "prod1.example.com",
        "architecture": "x64",
        "platform": "darwin"
    },
    "transactions": [
        {
            "id": "945254c5-67a5-417e-8a4e-aa29efcbfb79",
            "name": "GET /api/types",
            "type": "request",
            "duration": 32.592981,
            "result": "success",
            "timestamp": "2017-05-30T18:53:27.154Z",
            "context": {
                "request": {
                    "socket": {
                        "remote_address": "12.53.12.1",
                        "encrypted": true
                    },
                    "http_version": "1.1",
                    "method": "POST",
                    "url": {
                        "protocol": "https:",
                        "hostname": "www.example.com",
                        "port": "8080",
                        "pathname": "/p/a/t/h",
                        "search": "?query=string",
                        "hash": "#hash",
                        "raw": "/p/a/t/h?query=string#hash"
                    },
                    "headers": {
                        "user-agent": "Mozilla Chrome Edge",
                        "content-type": "text/html",
                        "cookie": "c1=v1; c2=v2",
                        "some-other-header": "foo",
                        "array": [
                            "foo",
                            "bar",
                            "baz"
                        ]
                    },
                    "cookies": {
                        "c1": "v1",
                        "c2": "v2"
                    },
                    "env": {
                        "SERVER_SOFTWARE": "nginx",
                        "GATEWAY_INTERFACE": "CGI/1.1"
                    },
                    "body": "Hello World"
                },
                "response": {
                    "status_code": 200,
                    "headers": {
                        "content-type": "application/json"
                    },
                    "headers_sent": true,
                    "finished": true
                },
                "user": {
                    "id": "99",
                    "username": "foo",
                    "email": "foo@example.com"
                },
                "tags": {
                    "organization_uuid": "9f0e9d64-c185-4d21-a6f4-4673ed561ec8"
                },
                "custom": {
                    "my_key": 1,
                    "some_other_value": "foo bar",
                    "and_objects": {
                        "foo": [
                            "bar",
                            "baz"
                        ]
                    }
                }
            },
            "traces": [
                {
                    "id": 0,
                    "parent": null,
                    "name": "SELECT FROM product_types",
                    "type": "db.postgresql.query",
                    "start": 2.83092,
                    "duration": 3.781912,
                    "stacktrace": [
                        {
                            "function": "onread",
                            "abs_path": "net.js",
                            "filename": "net.js",
                            "lineno": 547,
                            "in_app": false,
                            "vars": {
                              "key": "value"
                            },
                            "module": "some module",
                            "colno": 4,
                            "context_line": "line3",
                            "pre_context": [
                                "  var trans = this.currentTransaction",
                                ""
                            ],
                            "post_context": [
                                "    ins.currentTransaction = prev",
                                "    return result",
                                "}"
                            ]
                        },
                        {
                            "filename": "my2file.js",
                            "lineno": 10
                        }
                    ],
                    "context": {
                        "db": {
                            "instance": "customers",
                            "statement": "SELECT * FROM product_types WHERE user_id=?",
                            "type": "sql",
                            "user": "readonly_user"
                        }
                    }
                },
                {
                    "id": 1,
                    "parent": 0,
                    "name": "GET /api/types",
                    "type": "request",
                    "start": 0,
                    "duration": 32.592981
                },
                {
                    "id": 2,
                    "parent": 1,
                    "name": "GET /api/types",
                    "type": "request",
                    "start": 1.845,
                    "duration": 3.5642981,
                    "stacktrace": [],
                    "context": {}
                },
                {
                    "id": 3,
                    "parent": 2,
                    "name": "GET /api/types",
                    "type": "request",
                    "start": 0,
                    "duration": 13.9802981,
                    "stacktrace": null,
                    "context": null
                }
            ]
        },
        {
            "id": "85925e55-b43f-4340-a8e0-df1906ecbf7a",
            "name": "GET /api/types",
            "type": "request",
            "duration": 13.980558,
            "result": "failure",
            "timestamp": "2017-05-30T18:53:42.281Z",
            "traces": []
        },
        {
            "id": "85925e55-b43f-4340-a8e0-df1906ecbf78",
            "name": "GET /api/types",
            "type": "request",
            "duration": 13.980558,
            "result": "200",
            "timestamp": "2017-05-30T18:53:42Z"
        },
        {
            "id": "85925e55-b43f-4340-a8e0-df1906ecbfa9",
            "name": "GET /api/types",
            "type": "request",
            "duration": 13.980558,
            "result": "200",
            "timestamp": "2017-05-30T18:53:42.281999Z",
            "traces": [
                {
                    "name": "SELECT FROM product_types",
                    "type": "db.postgresql.query",
                    "start": 2.83092,
                    "duration": 3.781912,
                    "stacktrace": [],
                    "context": {
                        "db": {
                            "instance": "customers",
                            "statement": "SELECT * FROM product_types WHERE user_id=?",
                            "type": "sql",
                            "user": "readonly_user"
                        }
                    }
                }
            ]
        }
    ]
}

Payload with a minimal Transaction

edit
{
    "app": {
        "name": "app1",
        "agent": {
          "name": "python",
          "version": "1.0"
        }
    },
    "transactions": [
        {
            "id": "945254c5-67a5-417e-8a4e-aa29efcbfb79",
            "name": "GET /api/types",
            "type": "request",
            "duration": 32.592981,
            "timestamp": "2017-05-09T15:04:05.999999Z"
        }
    ]
}

Payload with a Transaction with a minimal Trace

edit
{
    "app": {
        "name": "app1",
        "agent": {
          "name": "python",
          "version": "1.0"
        }
    },
    "transactions": [
        {
            "id": "945254c5-67a5-417e-8a4e-aa29efcbfb79",
            "name": "GET /api/types",
            "type": "request",
            "duration": 32.592981,
            "timestamp": "2017-05-30T18:53:27.154Z",
            "traces": [
                {
                    "name": "GET /api/types",
                    "type": "request",
                    "start": 0,
                    "duration": 32.592981
                }
            ]
        }
    ]
}