/*! Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one or more contributor license agreements. * Licensed under the Elastic License 2.0; you may not use this file except in compliance with the Elastic License 2.0. */ (window.apm_bundle_jsonpfunction=window.apm_bundle_jsonpfunction||[]).push([[23],{1051:function(e,t,n){"use strict";n.r(t),n.d(t,"registerAssistantFunctions",(function(){return T}));var a=n(82),r=n(0);let i;!function(e){e.Transaction="transaction",e.ExitSpan="exit_span",e.Error="error"}(i||(i={}));var s=n(130);const o={type:"string",minLength:1};var c=n(17),p=n(9),d=n(1),u=n.n(d),h=n(21),m=n(73),l=n(122),g=n(138),f=n(93),y=n(479),v=n(88),b=n(95),w=n(12),_=n(108);async function T({pluginsStart:e,coreStart:t,registerContext:n,registerFunction:d,signal:T}){Object(a.createCallApmApi)(t),(await Object(a.callApmApi)("GET /internal/apm/has_data",{signal:T})).hasData&&(function({registerFunction:e}){e({contexts:["apm"],name:"get_apm_timeseries",descriptionForUser:r.i18n.translate("xpack.apm.observabilityAiAssistant.functions.registerGetApmTimeseries.descriptionForUser",{defaultMessage:"Display different APM metrics, like throughput, failure rate, or latency, for any service or all services, or any or all of its dependencies, both as a timeseries and as a single statistic. Additionally, the function will return any changes, such as spikes, step and trend changes, or dips. You can also use it to compare data by requesting two different time ranges, or for instance two different service versions"}),description:"Visualise and analyse different APM metrics, like throughput, failure rate, or latency, for any service or all services, or any or all of its dependencies, both as a timeseries and as a single statistic. A visualisation will be displayed above your reply - DO NOT attempt to display or generate an image yourself, or any other placeholder. Additionally, the function will return any changes, such as spikes, step and trend changes, or dips. You can also use it to compare data by requesting two different time ranges, or for instance two different service versions.",parameters:{type:"object",properties:{start:{type:"string",description:"The start of the time range, in Elasticsearch date math, like `now`."},end:{type:"string",description:"The end of the time range, in Elasticsearch date math, like `now-24h`."},stats:{type:"array",items:{type:"object",properties:{timeseries:{description:"The metric to be displayed",oneOf:[{type:"object",properties:{name:{type:"string",enum:["transaction_throughput","transaction_failure_rate"]},"transaction.type":{type:"string",description:"The transaction type"}},required:["name"]},{type:"object",properties:{name:{type:"string",enum:["exit_span_throughput","exit_span_failure_rate","exit_span_latency"]},"span.destination.service.resource":{type:"string",description:"The name of the downstream dependency for the service"}},required:["name"]},{type:"object",properties:{name:{type:"string",const:"error_event_rate"}},required:["name"]},{type:"object",properties:{name:{type:"string",const:"transaction_latency"},"transaction.type":{type:"string"},function:{type:"string",enum:["avg","p95","p99"]}},required:["name","function"]}]},"service.name":{...o,description:"The name of the service"},"service.environment":{description:"The environment that the service is running in. If undefined, all environments will be included. Only use this if you have confirmed the environment that the service is running in."},filter:{type:"string",description:"a KQL query to filter the data by. If no filter should be applied, leave it empty."},title:{type:"string",description:"A unique, human readable, concise title for this specific group series."},offset:{type:"string",description:"The offset. Right: 15m. 8h. 1d. Wrong: -15m. -8h. -1d."}},required:["service.name","timeseries","title"]}}},required:["stats","start","end"]}},(async({arguments:{stats:e,start:t,end:n}},r)=>await Object(a.callApmApi)("POST /internal/apm/assistant/get_apm_timeseries",{signal:r,params:{body:{stats:e,start:t,end:n}}})),(({arguments:e,response:t})=>{const n=Object(p.groupBy)(t.data,(e=>e.group)),{services:{uiSettings:a}}=Object(h.useKibana)(),r=Object(l.a)(a);return u.a.createElement(f.b,null,u.a.createElement(y.b,null,u.a.createElement(c.EuiFlexGroup,{direction:"column"},Object.values(n).map((e=>{const t=e[0].group,n=Object(_.a)(e),a=Object(w.n)(n,10,1e3);let i;switch(e[0].stat.timeseries.name){case"transaction_throughput":case"exit_span_throughput":case"error_event_rate":i=w.k;break;case"transaction_latency":case"exit_span_latency":i=Object(_.b)(a);break;case"transaction_failure_rate":case"exit_span_failure_rate":i=e=>Object(w.i)(e||0,100)}const s=e.map((e=>{let t;const n=e.data;switch(e.stat.timeseries.name){case"transaction_throughput":case"exit_span_throughput":t=v.a.THROUGHPUT;break;case"transaction_failure_rate":case"exit_span_failure_rate":t=v.a.FAILED_TRANSACTION_RATE;break;case"transaction_latency":t=e.stat.timeseries.function===b.a.p99?v.a.LATENCY_P99:e.stat.timeseries.function===b.a.p95?v.a.LATENCY_P95:v.a.LATENCY_AVG;break;case"exit_span_latency":t=v.a.LATENCY_AVG;break;case"error_event_rate":t=v.a.ERROR_OCCURRENCES}return{title:e.id,type:"line",color:Object(v.b)(t).currentPeriodColor,data:n}}));return u.a.createElement(c.EuiFlexItem,{grow:!1,key:t},u.a.createElement(c.EuiFlexGroup,{direction:"column",gutterSize:"s"},u.a.createElement(c.EuiFlexItem,null,u.a.createElement(c.EuiText,{size:"m"},t),u.a.createElement(g.a,{comparisonEnabled:!1,fetchStatus:m.a.SUCCESS,id:t,timeZone:r,timeseries:s,yLabelFormat:i}))))})))))}))}({registerFunction:d}),function({registerFunction:e}){e({name:"get_apm_error_document",contexts:["apm"],description:"Get a sample error document based on its grouping name. This also includes the \n stacktrace of the error, which might give you a hint as to what the cause is. \n ONLY use this for error events.",descriptionForUser:r.i18n.translate("xpack.apm.observabilityAiAssistant.functions.registerGetApmErrorDocument.descriptionForUser",{defaultMessage:"Get a sample error document based on its grouping name. This also includes the \n stacktrace of the error, which might give you a hint as to what the cause is."}),parameters:{type:"object",properties:{"error.grouping_name":{type:"string",description:"The grouping name of the error. Use the field value returned by get_apm_chart or get_correlation_values."},start:{type:"string",description:"The start of the time range, in Elasticsearch date math, lik e `now`."},end:{type:"string",description:"The end of the time range, in Elasticsearch date math, like `now-24h`."}},required:["start","end","error.grouping_name"]}},(async({arguments:e},t)=>Object(a.callApmApi)("GET /internal/apm/assistant/get_error_document",{signal:t,params:{query:e}})))}({registerFunction:d}),function({registerFunction:e}){e({name:"get_apm_correlations",contexts:["apm"],description:"Get field values that are more prominent in the foreground set than the \n background set. This can be useful in determining what attributes (like \n error.message, service.node.name or transaction.name) are contributing to for \n instance a higher latency. Another option is a time-based comparison, where you \n compare before and after a change point. In KQL, escaping happens with double \n quotes, not single quotes. Some characters that need escaping are: ':()\\/\". \n IF you need to filter, make sure the fields are available on the event, and \n ALWAYS put a field value in double quotes. Best: event.outcome:\"failure\". \n Wrong: event.outcome:'failure'. This is very important! ONLY use this function \n if you have something to compare it to.",descriptionForUser:r.i18n.translate("xpack.apm.observabilityAiAssistant.functions.registerGetApmCorrelationsFunction.descriptionForUser",{defaultMessage:"Get field values that are more prominent in the foreground set than the \n background set. This can be useful in determining what attributes (like \n error.message, service.node.name or transaction.name) are contributing to for \n instance a higher latency. Another option is a time-based comparison, where you \n compare before and after a change point."}),parameters:{type:"object",properties:{sets:{type:"array",items:{type:"object",properties:{label:{type:"string",description:"A unique, human readable label for the comparison set."},background:{description:"The background data set",$ref:"#/$defs/set"},foreground:{description:"The foreground data set. Needs to be a subset of the background set",$ref:"#/$defs/set"},event:{type:"string",enum:[i.Error,i.Transaction,i.ExitSpan]}},required:["background","foreground","event"]}}},required:["sets"],$defs:{set:{type:"object",properties:{"service.name":{type:"string",description:"The name of the service"},"service.environment":{type:"string",description:"The environment that the service is running in."},start:{type:"string",description:"The start of the time range, in Elasticsearch date math, like `now`."},end:{type:"string",description:"The end of the time range, in Elasticsearch date math, like `now-24h`."},filter:{type:"string",description:"a KQL query to filter the data by. Always escape, with double quotes. If no filter should be applied, leave it empty."},label:{type:"string",description:"A unique, human readable label."}},required:["service.name","start","end","label"]}}}},(async({arguments:e},t)=>Object(a.callApmApi)("POST /internal/apm/assistant/get_correlation_values",{signal:t,params:{body:e}})))}({registerFunction:d}),function({registerFunction:e}){e({name:"get_apm_downstream_dependencies",contexts:["apm"],description:"Get the downstream dependencies (services or uninstrumented backends) for a \n service. This allows you to map the dowstream dependency name to a service, by \n returning both span.destination.service.resource and service.name. Use this to \n drilldown further if needed.",descriptionForUser:r.i18n.translate("xpack.apm.observabilityAiAssistant.functions.registerGetApmDownstreamDependencies.descriptionForUser",{defaultMessage:"Get the downstream dependencies (services or uninstrumented backends) for a \n service. This allows you to map the dowstream dependency name to a service, by \n returning both span.destination.service.resource and service.name. Use this to \n drilldown further if needed."}),parameters:{type:"object",properties:{"service.name":{type:"string",description:"The name of the service"},"service.environment":{type:"string",description:"The environment that the service is running in"},start:{type:"string",description:"The start of the time range, in Elasticsearch date math, like `now`."},end:{type:"string",description:"The end of the time range, in Elasticsearch date math, like `now-24h`."}},required:["service.name","start","end"]}},(async({arguments:e},t)=>Object(a.callApmApi)("GET /internal/apm/assistant/get_downstream_dependencies",{signal:t,params:{query:e}})))}({registerFunction:d}),function({registerFunction:e}){e({name:"get_apm_service_summary",contexts:["apm"],description:"Gets a summary of a single service, including: the language, service version, \ndeployments, the environments, and the infrastructure that it is running in, for instance on how \nmany pods, and a list of its downstream dependencies. It also returns active \nalerts and anomalies.",descriptionForUser:r.i18n.translate("xpack.apm.observabilityAiAssistant.functions.registerGetApmServiceSummary.descriptionForUser",{defaultMessage:"Gets a summary of a single service, including: the language, service version, \ndeployments, the environments, and the infrastructure that it is running in, for instance on how \nmany pods, and a list of its downstream dependencies. It also returns active \nalerts and anomalies."}),parameters:{type:"object",properties:{"service.name":{...o,description:"The name of the service that should be summarized."},"service.environment":{...o,description:"The environment that the service is running in"},start:{...o,description:"The start of the time range, in Elasticsearch date math, like `now`."},end:{...o,description:"The end of the time range, in Elasticsearch date math, like `now-24h`."}},required:["service.name","start","end"]}},(async({arguments:e},t)=>Object(a.callApmApi)("GET /internal/apm/assistant/get_service_summary",{signal:t,params:{query:e}})))}({registerFunction:d}),function({registerFunction:e}){e({name:"get_apm_services_list",contexts:["apm"],description:"Gets a list of services",descriptionForUser:r.i18n.translate("xpack.apm.observabilityAiAssistant.functions.registerGetApmServicesList.descriptionForUser",{defaultMessage:"Gets the list of monitored services, their health status, and alerts."}),parameters:{type:"object",additionalProperties:!1,properties:{"service.environment":{...o,description:"Optionally filter the services by the environments that they are running in"},start:{...o,description:"The start of the time range, in Elasticsearch date math, like `now`."},end:{...o,description:"The end of the time range, in Elasticsearch date math, like `now-24h`."},healthStatus:{type:"array",description:"Filter service list by health status",additionalProperties:!1,additionalItems:!1,items:{type:"string",enum:[s.a.unknown,s.a.healthy,s.a.warning,s.a.critical]}}},required:["start","end"]}},(async({arguments:e},t)=>Object(a.callApmApi)("POST /internal/apm/assistant/get_services_list",{signal:t,params:{body:e}})))}({registerFunction:d}),n({name:"apm",description:"\n When analyzing APM data, prefer the APM specific functions over the generic Lens,\n Elasticsearch or Kibana ones, unless those are explicitly requested by the user.\n\n When requesting metrics for a service, make sure you also know what environment\n it is running in. Metrics aggregated over multiple environments are useless.\n\n There are four important data types in Elastic APM. Each of them have the\n following fields:\n - service.name: the name of the service\n - service.node.name: the id of the service instance (often the hostname)\n - service.environment: the environment (often production, development)\n - agent.name: the name of the agent (go, java, etc)\n\n The four data types are transactions, exit spans, error events, and application\n metrics.\n\n Transactions have three metrics: throughput, failure rate, and latency. The\n fields are:\n\n - transaction.type: often request or page-load (the main transaction types),\n but can also be worker, or route-change.\n - transaction.name: The name of the transaction group, often something like\n 'GET /api/product/:productId'\n - transaction.result: The result. Used to capture HTTP response codes\n (2xx,3xx,4xx,5xx) for request transactions.\n - event.outcome: whether the transaction was succesful or not. success,\n failure, or unknown.\n\n Exit spans have three metrics: throughput, failure rate and latency. The fields\n are:\n - span.type: db, external\n - span.subtype: the type of database (redis, postgres) or protocol (http, grpc)\n - span.destination.service.resource: the address of the destination of the call\n - event.outcome: whether the transaction was succesful or not. success,\n failure, or unknown.\n\n Error events have one metric, error event rate. The fields are:\n - error.grouping_name: a human readable keyword that identifies the error group\n\n For transaction metrics we also collect anomalies. These are scored 0 (low) to\n 100 (critical).\n\n For root cause analysis, locate a change point in the relevant metrics for a\n service or downstream dependency. You can locate a change point by using a\n sliding window, e.g. start with a small time range, like 30m, and make it\n bigger until you identify a change point. It's very important to identify a\n change point. If you don't have a change point, ask the user for next steps.\n You can also use an anomaly or a deployment as a change point. Then, compare\n data before the change with data after the change. You can either use the\n groupBy parameter in get_apm_chart to get the most occuring values in a certain\n data set, or you can use correlations to see for which field and value the\n frequency has changed when comparing the foreground set to the background set.\n This is useful when comparing data from before the change point with after the\n change point. For instance, you might see a specific error pop up more often\n after the change point.\n\n When comparing anomalies and changes in timeseries, first, zoom in to a smaller\n time window, at least 30 minutes before and 30 minutes after the change\n occured. E.g., if the anomaly occured at 2023-07-05T08:15:00.000Z, request a\n time window that starts at 2023-07-05T07:45:00.000Z and ends at\n 2023-07-05T08:45:00.000Z. When comparing changes in different timeseries and\n anomalies to determine a correlation, make sure to compare the timestamps. If\n in doubt, rate the likelihood of them being related, given the time difference,\n between 1 and 10. If below 5, assume it's not related. Mention this likelihood\n (and the time difference) to the user.\n\n Your goal is to help the user determine the root cause of an issue quickly and\n transparently. If you see a change or\n anomaly in a metric for a service, try to find similar changes in the metrics\n for the traffic to its downstream dependencies, by comparing transaction\n metrics to span metrics. To inspect the traffic from one service to a\n downstream dependency, first get the downstream dependencies for a service,\n then get the span metrics from that service (`service.name`) to its\n downstream dependency (`span.destination.service.resource`). For instance,\n for an anomaly in throughput, first inspect `transaction_throughput` for\n `service.name`. Then, inspect `exit_span_throughput` for its downstream\n dependencies, by grouping by `span.destination.service.resource`. Repeat this\n process over the next service its downstream dependencies until you identify a\n root cause. If you can not find any similar changes, use correlations or\n grouping to find attributes that could be causes for the change."}))}}}]);