1// Licensed to Elasticsearch B.V. under one or more contributor
2// license agreements. See the NOTICE file distributed with
3// this work for additional information regarding copyright
4// ownership. Elasticsearch B.V. licenses this file to you under
5// the Apache License, Version 2.0 (the "License"); you may
6// not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9//     http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied.  See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18package model
19
20import (
21	"net/http"
22	"net/url"
23	"time"
24)
25
26// Service represents the service handling transactions being traced.
27type Service struct {
28	// Name is the immutable name of the service.
29	Name string `json:"name,omitempty"`
30
31	// Version is the version of the service, if it has one.
32	Version string `json:"version,omitempty"`
33
34	// Environment is the name of the service's environment, if it has
35	// one, e.g. "production" or "staging".
36	Environment string `json:"environment,omitempty"`
37
38	// Agent holds information about the Elastic APM agent tracing this
39	// service's transactions.
40	Agent *Agent `json:"agent,omitempty"`
41
42	// Framework holds information about the service's framework, if any.
43	Framework *Framework `json:"framework,omitempty"`
44
45	// Language holds information about the programming language in which
46	// the service is written.
47	Language *Language `json:"language,omitempty"`
48
49	// Runtime holds information about the programming language runtime
50	// running this service.
51	Runtime *Runtime `json:"runtime,omitempty"`
52}
53
54// Agent holds information about the Elastic APM agent.
55type Agent struct {
56	// Name is the name of the Elastic APM agent, e.g. "Go".
57	Name string `json:"name"`
58
59	// Version is the version of the Elastic APM agent, e.g. "1.0.0".
60	Version string `json:"version"`
61}
62
63// Framework holds information about the framework (typically web)
64// used by the service.
65type Framework struct {
66	// Name is the name of the framework.
67	Name string `json:"name"`
68
69	// Version is the version of the framework.
70	Version string `json:"version"`
71}
72
73// Language holds information about the programming language used.
74type Language struct {
75	// Name is the name of the programming language.
76	Name string `json:"name"`
77
78	// Version is the version of the programming language.
79	Version string `json:"version,omitempty"`
80}
81
82// Runtime holds information about the programming language runtime.
83type Runtime struct {
84	// Name is the name of the programming language runtime.
85	Name string `json:"name"`
86
87	// Version is the version of the programming language runtime.
88	Version string `json:"version"`
89}
90
91// System represents the system (operating system and machine) running the
92// service.
93type System struct {
94	// Architecture is the system's hardware architecture.
95	Architecture string `json:"architecture,omitempty"`
96
97	// Hostname is the system's hostname.
98	Hostname string `json:"hostname,omitempty"`
99
100	// Platform is the system's platform, or operating system name.
101	Platform string `json:"platform,omitempty"`
102
103	// Container describes the container running the service.
104	Container *Container `json:"container,omitempty"`
105
106	// Kubernetes describes the kubernetes node and pod running the service.
107	Kubernetes *Kubernetes `json:"kubernetes,omitempty"`
108}
109
110// Process represents an operating system process.
111type Process struct {
112	// Pid is the process ID.
113	Pid int `json:"pid"`
114
115	// Ppid is the parent process ID, if known.
116	Ppid *int `json:"ppid,omitempty"`
117
118	// Title is the title of the process.
119	Title string `json:"title,omitempty"`
120
121	// Argv holds the command line arguments used to start the process.
122	Argv []string `json:"argv,omitempty"`
123}
124
125// Container represents the container (e.g. Docker) running the service.
126type Container struct {
127	// ID is the unique container ID.
128	ID string `json:"id"`
129}
130
131// Kubernetes describes properties of the Kubernetes node and pod in which
132// the service is running.
133type Kubernetes struct {
134	// Namespace names the Kubernetes namespace in which the pod exists.
135	Namespace string `json:"namespace,omitempty"`
136
137	// Node describes the Kubernetes node running the service's pod.
138	Node *KubernetesNode `json:"node,omitempty"`
139
140	// Pod describes the Kubernetes pod running the service.
141	Pod *KubernetesPod `json:"pod,omitempty"`
142}
143
144// KubernetesNode describes a Kubernetes node.
145type KubernetesNode struct {
146	// Name holds the node name.
147	Name string `json:"name,omitempty"`
148}
149
150// KubernetesPod describes a Kubernetes pod.
151type KubernetesPod struct {
152	// Name holds the pod name.
153	Name string `json:"name,omitempty"`
154
155	// UID holds the pod UID.
156	UID string `json:"uid,omitempty"`
157}
158
159// Transaction represents a transaction handled by the service.
160type Transaction struct {
161	// ID holds the 64-bit hex-encoded transaction ID.
162	ID SpanID `json:"id"`
163
164	// TraceID holds the ID of the trace that this transaction is a part of.
165	TraceID TraceID `json:"trace_id"`
166
167	// ParentID holds the ID of the transaction's parent span or transaction.
168	ParentID SpanID `json:"parent_id,omitempty"`
169
170	// Name holds the name of the transaction.
171	Name string `json:"name"`
172
173	// Type identifies the service-domain specific type of the request,
174	// e.g. "request" or "backgroundjob".
175	Type string `json:"type"`
176
177	// Timestamp holds the time at which the transaction started.
178	Timestamp Time `json:"timestamp"`
179
180	// Duration records how long the transaction took to complete,
181	// in milliseconds.
182	Duration float64 `json:"duration"`
183
184	// Result holds the result of the transaction, e.g. the status code
185	// for HTTP requests.
186	Result string `json:"result,omitempty"`
187
188	// Context holds contextual information relating to the transaction.
189	Context *Context `json:"context,omitempty"`
190
191	// Sampled indicates that the transaction was sampled, and
192	// includes all available information. Non-sampled transactions
193	// omit Context.
194	//
195	// If Sampled is unspecified (nil), it is equivalent to setting
196	// it to true.
197	Sampled *bool `json:"sampled,omitempty"`
198
199	// SpanCount holds statistics on spans within a transaction.
200	SpanCount SpanCount `json:"span_count"`
201}
202
203// SpanCount holds statistics on spans within a transaction.
204type SpanCount struct {
205	// Dropped holds the number of spans dropped within a transaction.
206	// This does not include spans that were started and dropped due
207	// to full buffers, network errors, etc.
208	Dropped int `json:"dropped"`
209
210	// Started holds the number of spans started within a transaction.
211	Started int `json:"started"`
212}
213
214// Span represents a span within a transaction.
215type Span struct {
216	// Name holds the name of the span.
217	Name string `json:"name"`
218
219	// Timestamp holds the time at which the span started.
220	Timestamp Time `json:"timestamp"`
221
222	// Duration holds the duration of the span, in milliseconds.
223	Duration float64 `json:"duration"`
224
225	// Type identifies the overarching type of the span,
226	// e.g. "db" or "external".
227	Type string `json:"type"`
228
229	// Subtype identifies the subtype of the span,
230	// e.g. "mysql" or "http".
231	Subtype string `json:"subtype,omitempty"`
232
233	// Action identifies the action that is being undertaken, e.g. "query".
234	Action string `json:"action,omitempty"`
235
236	// ID holds the ID of the span.
237	ID SpanID `json:"id"`
238
239	// TransactionID holds the ID of the transaction of which the span is a part.
240	TransactionID SpanID `json:"transaction_id"`
241
242	// TraceID holds the ID of the trace that this span is a part of.
243	TraceID TraceID `json:"trace_id"`
244
245	// ParentID holds the ID of the span's parent (span or transaction).
246	ParentID SpanID `json:"parent_id,omitempty"`
247
248	// Context holds contextual information relating to the span.
249	Context *SpanContext `json:"context,omitempty"`
250
251	// Stacktrace holds stack frames corresponding to the span.
252	Stacktrace []StacktraceFrame `json:"stacktrace,omitempty"`
253}
254
255// SpanContext holds contextual information relating to the span.
256type SpanContext struct {
257	// Database holds contextual information for database
258	// operation spans.
259	Database *DatabaseSpanContext `json:"db,omitempty"`
260
261	// HTTP holds contextual information for HTTP client request spans.
262	HTTP *HTTPSpanContext `json:"http,omitempty"`
263
264	// Tags holds user-defined key/value pairs.
265	Tags StringMap `json:"tags,omitempty"`
266}
267
268// DatabaseSpanContext holds contextual information for database
269// operation spans.
270type DatabaseSpanContext struct {
271	// Instance holds the database instance name.
272	Instance string `json:"instance,omitempty"`
273
274	// Statement holds the database statement (e.g. query).
275	Statement string `json:"statement,omitempty"`
276
277	// Type holds the database type. For any SQL database,
278	// this should be "sql"; for others, the lower-cased
279	// database category, e.g. "cassandra", "hbase", "redis".
280	Type string `json:"type,omitempty"`
281
282	// User holds the username used for database access.
283	User string `json:"user,omitempty"`
284}
285
286// HTTPSpanContext holds contextual information for HTTP client request spans.
287type HTTPSpanContext struct {
288	// URL is the request URL.
289	URL *url.URL
290
291	// StatusCode holds the HTTP response status code.
292	StatusCode int `json:"status_code,omitempty"`
293}
294
295// Context holds contextual information relating to a transaction or error.
296type Context struct {
297	// Custom holds custom context relating to the transaction or error.
298	Custom IfaceMap `json:"custom,omitempty"`
299
300	// Request holds details of the HTTP request relating to the
301	// transaction or error, if relevant.
302	Request *Request `json:"request,omitempty"`
303
304	// Response holds details of the HTTP response relating to the
305	// transaction or error, if relevant.
306	Response *Response `json:"response,omitempty"`
307
308	// User holds details of the authenticated user relating to the
309	// transaction or error, if relevant.
310	User *User `json:"user,omitempty"`
311
312	// Tags holds user-defined key/value pairs.
313	Tags StringMap `json:"tags,omitempty"`
314
315	// Service holds values to overrides service-level metadata.
316	Service *Service `json:"service,omitempty"`
317}
318
319// User holds information about an authenticated user.
320type User struct {
321	// Username holds the username of the user.
322	Username string `json:"username,omitempty"`
323
324	// ID identifies the user, e.g. a primary key. This may be
325	// a string or number.
326	ID string `json:"id,omitempty"`
327
328	// Email holds the email address of the user.
329	Email string `json:"email,omitempty"`
330}
331
332// Error represents an error occurring in the service.
333type Error struct {
334	// Timestamp holds the time at which the error occurred.
335	Timestamp Time `json:"timestamp"`
336
337	// ID holds the 128-bit hex-encoded error ID.
338	ID TraceID `json:"id"`
339
340	// TraceID holds the ID of the trace within which the error occurred.
341	TraceID TraceID `json:"trace_id,omitempty"`
342
343	// ParentID holds the ID of the transaction within which the error
344	// occurred.
345	ParentID SpanID `json:"parent_id,omitempty"`
346
347	// TransactionID holds the ID of the transaction within which the error occurred.
348	TransactionID SpanID `json:"transaction_id,omitempty"`
349
350	// Culprit holds the name of the function which
351	// produced the error.
352	Culprit string `json:"culprit,omitempty"`
353
354	// Context holds contextual information relating to the error.
355	Context *Context `json:"context,omitempty"`
356
357	// Exception holds details of the exception (error or panic)
358	// to which this error relates.
359	Exception Exception `json:"exception,omitempty"`
360
361	// Log holds additional information added when logging the error.
362	Log Log `json:"log,omitempty"`
363
364	// Transaction holds information about the transaction within which the error occurred.
365	Transaction ErrorTransaction `json:"transaction,omitempty"`
366}
367
368// ErrorTransaction holds information about the transaction within which an error occurred.
369type ErrorTransaction struct {
370	// Sampled indicates that the transaction was sampled.
371	Sampled *bool `json:"sampled,omitempty"`
372
373	// Type holds the transaction type.
374	Type string `json:"type,omitempty"`
375}
376
377// Exception represents an exception: an error or panic.
378type Exception struct {
379	// Message holds the error message.
380	Message string `json:"message"`
381
382	// Code holds the error code. This may be a number or a string.
383	Code ExceptionCode `json:"code,omitempty"`
384
385	// Type holds the type of the exception.
386	Type string `json:"type,omitempty"`
387
388	// Module holds the exception type's module namespace.
389	Module string `json:"module,omitempty"`
390
391	// Attributes holds arbitrary exception-type specific attributes.
392	Attributes map[string]interface{} `json:"attributes,omitempty"`
393
394	// Stacktrace holds stack frames corresponding to the exception.
395	Stacktrace []StacktraceFrame `json:"stacktrace,omitempty"`
396
397	// Handled indicates whether or not the error was caught and handled.
398	Handled bool `json:"handled"`
399}
400
401// ExceptionCode represents an exception code as either a number or a string.
402type ExceptionCode struct {
403	String string
404	Number float64
405}
406
407// StacktraceFrame describes a stack frame.
408type StacktraceFrame struct {
409	// AbsolutePath holds the absolute path of the source file for the
410	// stack frame.
411	AbsolutePath string `json:"abs_path,omitempty"`
412
413	// File holds the base filename of the source file for the stack frame.
414	File string `json:"filename"`
415
416	// Line holds the line number of the source for the stack frame.
417	Line int `json:"lineno"`
418
419	// Column holds the column number of the source for the stack frame.
420	Column *int `json:"colno,omitempty"`
421
422	// Module holds the module to which the frame belongs. For Go, we
423	// use the package path (e.g. "net/http").
424	Module string `json:"module,omitempty"`
425
426	// Function holds the name of the function to which the frame belongs.
427	Function string `json:"function,omitempty"`
428
429	// LibraryFrame indicates whether or not the frame corresponds to
430	// library or user code.
431	LibraryFrame bool `json:"library_frame,omitempty"`
432
433	// ContextLine holds the line of source code to which the frame
434	// corresponds.
435	ContextLine string `json:"context_line,omitempty"`
436
437	// PreContext holds zero or more lines of source code preceding the
438	// line corresponding to the frame.
439	PreContext []string `json:"pre_context,omitempty"`
440
441	// PostContext holds zero or more lines of source code proceeding the
442	// line corresponding to the frame.
443	PostContext []string `json:"post_context,omitempty"`
444
445	// Vars holds local variables for this stack frame.
446	Vars map[string]interface{} `json:"vars,omitempty"`
447}
448
449// Log holds additional information added when logging an error.
450type Log struct {
451	// Message holds the logged error message.
452	Message string `json:"message"`
453
454	// Level holds the severity of the log record.
455	Level string `json:"level,omitempty"`
456
457	// LoggerName holds the name of the logger used.
458	LoggerName string `json:"logger_name,omitempty"`
459
460	// ParamMessage holds a parameterized message,  e.g.
461	// "Could not connect to %s". The string is not interpreted,
462	// but may be used for grouping errors.
463	ParamMessage string `json:"param_message,omitempty"`
464
465	// Stacktrace holds stack frames corresponding to the error.
466	Stacktrace []StacktraceFrame `json:"stacktrace,omitempty"`
467}
468
469// Request represents an HTTP request.
470type Request struct {
471	// URL is the request URL.
472	URL URL `json:"url"`
473
474	// Method holds the HTTP request method.
475	Method string `json:"method"`
476
477	// Headers holds the request headers.
478	Headers Headers `json:"headers,omitempty"`
479
480	// Body holds the request body, if body capture is enabled.
481	Body *RequestBody `json:"body,omitempty"`
482
483	// HTTPVersion holds the HTTP version of the request.
484	HTTPVersion string `json:"http_version,omitempty"`
485
486	// Cookies holds the parsed cookies.
487	Cookies Cookies `json:"cookies,omitempty"`
488
489	// Env holds environment information passed from the
490	// web framework to the request handler.
491	Env map[string]string `json:"env,omitempty"`
492
493	// Socket holds transport-level information.
494	Socket *RequestSocket `json:"socket,omitempty"`
495}
496
497// Cookies holds a collection of HTTP cookies.
498type Cookies []*http.Cookie
499
500// RequestBody holds a request body.
501//
502// Exactly one of Raw or Form must be set.
503type RequestBody struct {
504	// Raw holds the raw body content.
505	Raw string
506
507	// Form holds the form data from POST, PATCH, or PUT body parameters.
508	Form url.Values
509}
510
511// Headers holds a collection of HTTP headers.
512type Headers []Header
513
514// Header holds an HTTP header, with one or more values.
515type Header struct {
516	Key    string
517	Values []string
518}
519
520// RequestSocket holds transport-level information relating to an HTTP request.
521type RequestSocket struct {
522	// Encrypted indicates whether or not the request was sent
523	// as an SSL/HTTPS request.
524	Encrypted bool `json:"encrypted,omitempty"`
525
526	// RemoteAddress holds the remote address for the request.
527	RemoteAddress string `json:"remote_address,omitempty"`
528}
529
530// URL represents a server-side (transaction) request URL,
531// broken down into its constituent parts.
532type URL struct {
533	// Full is the full URL, e.g.
534	// "https://example.com:443/search/?q=elasticsearch#top".
535	Full string `json:"full,omitempty"`
536
537	// Protocol is the scheme of the URL, e.g. "https".
538	Protocol string `json:"protocol,omitempty"`
539
540	// Hostname is the hostname for the URL, e.g. "example.com".
541	Hostname string `json:"hostname,omitempty"`
542
543	// Port is the port number in the URL, e.g. "443".
544	Port string `json:"port,omitempty"`
545
546	// Path is the path of the URL, e.g. "/search".
547	Path string `json:"pathname,omitempty"`
548
549	// Search is the query string of the URL, e.g. "q=elasticsearch".
550	Search string `json:"search,omitempty"`
551
552	// Hash is the fragment for references, e.g. "top" in the
553	// URL example provided for Full.
554	Hash string `json:"hash,omitempty"`
555}
556
557// Response represents an HTTP response.
558type Response struct {
559	// StatusCode holds the HTTP response status code.
560	StatusCode int `json:"status_code,omitempty"`
561
562	// Headers holds the response headers.
563	Headers Headers `json:"headers,omitempty"`
564
565	// HeadersSent indicates whether or not headers were sent
566	// to the client.
567	HeadersSent *bool `json:"headers_sent,omitempty"`
568
569	// Finished indicates whether or not the response was finished.
570	Finished *bool `json:"finished,omitempty"`
571}
572
573// Time is a timestamp, formatted as a number of microseconds since January 1, 1970 UTC.
574type Time time.Time
575
576// TraceID holds a 128-bit trace ID.
577type TraceID [16]byte
578
579// SpanID holds a 64-bit span ID. Despite its name, this is used for
580// both spans and transactions.
581type SpanID [8]byte
582
583// Metrics holds a set of metric samples, with an optional set of labels.
584type Metrics struct {
585	// Timestamp holds the time at which the metric samples were taken.
586	Timestamp Time `json:"timestamp"`
587
588	// Transaction optionally holds the name and type of transactions
589	// with which these metrics are associated.
590	Transaction MetricsTransaction `json:"transaction,omitempty"`
591
592	// Span optionally holds the type and subtype of the spans with
593	// which these metrics are associated.
594	Span MetricsSpan `json:"span,omitempty"`
595
596	// Labels holds a set of labels associated with the metrics.
597	// The labels apply uniformly to all metric samples in the set.
598	//
599	// NOTE(axw) the schema calls the field "tags", but we use
600	// "labels" for agent-internal consistency. Labels aligns better
601	// with the common schema, anyway.
602	Labels StringMap `json:"tags,omitempty"`
603
604	// Samples holds a map of metric samples, keyed by metric name.
605	Samples map[string]Metric `json:"samples"`
606}
607
608// MetricsTransaction holds transaction identifiers for metrics.
609type MetricsTransaction struct {
610	Type string `json:"type,omitempty"`
611	Name string `json:"name,omitempty"`
612}
613
614// MetricsSpan holds span identifiers for metrics.
615type MetricsSpan struct {
616	Type    string `json:"type,omitempty"`
617	Subtype string `json:"subtype,omitempty"`
618}
619
620// Metric holds metric values.
621type Metric struct {
622	// Value holds the metric value.
623	Value float64 `json:"value"`
624}
625