blob: 0882692cb6c3983791ef3031c2dd41383ac7470f [file] [log] [blame]
"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[7722],{3905:(t,e,n)=>{n.d(e,{Zo:()=>s,kt:()=>f});var r=n(7294);function a(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function i(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);e&&(r=r.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,r)}return n}function l(t){for(var e=1;e<arguments.length;e++){var n=null!=arguments[e]?arguments[e]:{};e%2?i(Object(n),!0).forEach((function(e){a(t,e,n[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(n)):i(Object(n)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(n,e))}))}return t}function o(t,e){if(null==t)return{};var n,r,a=function(t,e){if(null==t)return{};var n,r,a={},i=Object.keys(t);for(r=0;r<i.length;r++)n=i[r],e.indexOf(n)>=0||(a[n]=t[n]);return a}(t,e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(r=0;r<i.length;r++)n=i[r],e.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(t,n)&&(a[n]=t[n])}return a}var d=r.createContext({}),u=function(t){var e=r.useContext(d),n=e;return t&&(n="function"==typeof t?t(e):l(l({},e),t)),n},s=function(t){var e=u(t.components);return r.createElement(d.Provider,{value:e},t.children)},m="mdxType",p={inlineCode:"code",wrapper:function(t){var e=t.children;return r.createElement(r.Fragment,{},e)}},c=r.forwardRef((function(t,e){var n=t.components,a=t.mdxType,i=t.originalType,d=t.parentName,s=o(t,["components","mdxType","originalType","parentName"]),m=u(n),c=a,f=m["".concat(d,".").concat(c)]||m[c]||p[c]||i;return n?r.createElement(f,l(l({ref:e},s),{},{components:n})):r.createElement(f,l({ref:e},s))}));function f(t,e){var n=arguments,a=e&&e.mdxType;if("string"==typeof t||a){var i=n.length,l=new Array(i);l[0]=c;var o={};for(var d in e)hasOwnProperty.call(e,d)&&(o[d]=e[d]);o.originalType=t,o[m]="string"==typeof t?t:a,l[1]=o;for(var u=2;u<i;u++)l[u]=n[u];return r.createElement.apply(null,l)}return r.createElement.apply(null,n)}c.displayName="MDXCreateElement"},2803:(t,e,n)=>{n.r(e),n.d(e,{assets:()=>s,contentTitle:()=>d,default:()=>f,frontMatter:()=>o,metadata:()=>u,toc:()=>m});var r=n(7462),a=n(3366),i=(n(7294),n(3905)),l=["components"],o={id:"influxdb-emitter",title:"InfluxDB Emitter"},d=void 0,u={unversionedId:"development/extensions-contrib/influxdb-emitter",id:"development/extensions-contrib/influxdb-emitter",title:"InfluxDB Emitter",description:"\x3c!--",source:"@site/docs/26.0.0/development/extensions-contrib/influxdb-emitter.md",sourceDirName:"development/extensions-contrib",slug:"/development/extensions-contrib/influxdb-emitter",permalink:"/docs/26.0.0/development/extensions-contrib/influxdb-emitter",draft:!1,tags:[],version:"current",frontMatter:{id:"influxdb-emitter",title:"InfluxDB Emitter"}},s={},m=[{value:"Introduction",id:"introduction",level:2},{value:"Configuration",id:"configuration",level:2},{value:"InfluxDB Line Protocol",id:"influxdb-line-protocol",level:2}],p={toc:m},c="wrapper";function f(t){var e=t.components,n=(0,a.Z)(t,l);return(0,i.kt)(c,(0,r.Z)({},p,n,{components:e,mdxType:"MDXLayout"}),(0,i.kt)("p",null,"To use this Apache Druid extension, ",(0,i.kt)("a",{parentName:"p",href:"/docs/26.0.0/development/extensions#loading-extensions"},"include")," ",(0,i.kt)("inlineCode",{parentName:"p"},"druid-influxdb-emitter")," in the extensions load list."),(0,i.kt)("h2",{id:"introduction"},"Introduction"),(0,i.kt)("p",null,"This extension emits druid metrics to ",(0,i.kt)("a",{parentName:"p",href:"https://www.influxdata.com/time-series-platform/influxdb/"},"InfluxDB")," over HTTP. Currently this emitter only emits service metric events to InfluxDB (See ",(0,i.kt)("a",{parentName:"p",href:"/docs/26.0.0/operations/metrics"},"Druid metrics")," for a list of metrics).\nWhen a metric event is fired it is added to a queue of events. After a configurable amount of time, the events on the queue are transformed to InfluxDB's line protocol\nand POSTed to the InfluxDB HTTP API. The entire queue is flushed at this point. The queue is also flushed as the emitter is shutdown."),(0,i.kt)("p",null,"Note that authentication and authorization must be ",(0,i.kt)("a",{parentName:"p",href:"https://docs.influxdata.com/influxdb/v1.7/administration/authentication_and_authorization/"},"enabled")," on the InfluxDB server."),(0,i.kt)("h2",{id:"configuration"},"Configuration"),(0,i.kt)("p",null,"All the configuration parameters for the influxdb emitter are under ",(0,i.kt)("inlineCode",{parentName:"p"},"druid.emitter.influxdb"),"."),(0,i.kt)("table",null,(0,i.kt)("thead",{parentName:"table"},(0,i.kt)("tr",{parentName:"thead"},(0,i.kt)("th",{parentName:"tr",align:null},"Property"),(0,i.kt)("th",{parentName:"tr",align:null},"Description"),(0,i.kt)("th",{parentName:"tr",align:null},"Required?"),(0,i.kt)("th",{parentName:"tr",align:null},"Default"))),(0,i.kt)("tbody",{parentName:"table"},(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("inlineCode",{parentName:"td"},"druid.emitter.influxdb.hostname")),(0,i.kt)("td",{parentName:"tr",align:null},"The hostname of the InfluxDB server."),(0,i.kt)("td",{parentName:"tr",align:null},"Yes"),(0,i.kt)("td",{parentName:"tr",align:null},"N/A")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("inlineCode",{parentName:"td"},"druid.emitter.influxdb.port")),(0,i.kt)("td",{parentName:"tr",align:null},"The port of the InfluxDB server."),(0,i.kt)("td",{parentName:"tr",align:null},"No"),(0,i.kt)("td",{parentName:"tr",align:null},"8086")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("inlineCode",{parentName:"td"},"druid.emitter.influxdb.protocol")),(0,i.kt)("td",{parentName:"tr",align:null},"The protocol used to send metrics to InfluxDB. One of http/https"),(0,i.kt)("td",{parentName:"tr",align:null},"No"),(0,i.kt)("td",{parentName:"tr",align:null},"http")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("inlineCode",{parentName:"td"},"druid.emitter.influxdb.trustStorePath")),(0,i.kt)("td",{parentName:"tr",align:null},"The path to the trustStore to be used for https"),(0,i.kt)("td",{parentName:"tr",align:null},"No"),(0,i.kt)("td",{parentName:"tr",align:null},"none")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("inlineCode",{parentName:"td"},"druid.emitter.influxdb.trustStoreType")),(0,i.kt)("td",{parentName:"tr",align:null},"The trustStore type to be used for https"),(0,i.kt)("td",{parentName:"tr",align:null},"No"),(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("inlineCode",{parentName:"td"},"jks"))),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("inlineCode",{parentName:"td"},"druid.emitter.influxdb.trustStorePassword")),(0,i.kt)("td",{parentName:"tr",align:null},"The trustStore password to be used for https"),(0,i.kt)("td",{parentName:"tr",align:null},"No"),(0,i.kt)("td",{parentName:"tr",align:null},"none")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("inlineCode",{parentName:"td"},"druid.emitter.influxdb.databaseName")),(0,i.kt)("td",{parentName:"tr",align:null},"The name of the database in InfluxDB."),(0,i.kt)("td",{parentName:"tr",align:null},"Yes"),(0,i.kt)("td",{parentName:"tr",align:null},"N/A")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("inlineCode",{parentName:"td"},"druid.emitter.influxdb.maxQueueSize")),(0,i.kt)("td",{parentName:"tr",align:null},"The size of the queue that holds events."),(0,i.kt)("td",{parentName:"tr",align:null},"No"),(0,i.kt)("td",{parentName:"tr",align:null},"Integer.MAX_VALUE(=2^31-1)")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("inlineCode",{parentName:"td"},"druid.emitter.influxdb.flushPeriod")),(0,i.kt)("td",{parentName:"tr",align:null},"How often (in milliseconds) the events queue is parsed into Line Protocol and POSTed to InfluxDB."),(0,i.kt)("td",{parentName:"tr",align:null},"No"),(0,i.kt)("td",{parentName:"tr",align:null},"60000")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("inlineCode",{parentName:"td"},"druid.emitter.influxdb.flushDelay")),(0,i.kt)("td",{parentName:"tr",align:null},"How long (in milliseconds) the scheduled method will wait until it first runs."),(0,i.kt)("td",{parentName:"tr",align:null},"No"),(0,i.kt)("td",{parentName:"tr",align:null},"60000")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("inlineCode",{parentName:"td"},"druid.emitter.influxdb.influxdbUserName")),(0,i.kt)("td",{parentName:"tr",align:null},"The username for authenticating with the InfluxDB database."),(0,i.kt)("td",{parentName:"tr",align:null},"Yes"),(0,i.kt)("td",{parentName:"tr",align:null},"N/A")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("inlineCode",{parentName:"td"},"druid.emitter.influxdb.influxdbPassword")),(0,i.kt)("td",{parentName:"tr",align:null},"The password of the database authorized user"),(0,i.kt)("td",{parentName:"tr",align:null},"Yes"),(0,i.kt)("td",{parentName:"tr",align:null},"N/A")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("inlineCode",{parentName:"td"},"druid.emitter.influxdb.dimensionWhitelist")),(0,i.kt)("td",{parentName:"tr",align:null},"A whitelist of metric dimensions to include as tags"),(0,i.kt)("td",{parentName:"tr",align:null},"No"),(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("inlineCode",{parentName:"td"},'["dataSource","type","numMetrics","numDimensions","threshold","dimension","taskType","taskStatus","tier"]'))))),(0,i.kt)("h2",{id:"influxdb-line-protocol"},"InfluxDB Line Protocol"),(0,i.kt)("p",null,"An example of how this emitter parses a Druid metric event into InfluxDB's ",(0,i.kt)("a",{parentName:"p",href:"https://docs.influxdata.com/influxdb/v1.7/write_protocols/line_protocol_reference/"},"line protocol")," is given here:"),(0,i.kt)("p",null,"The syntax of the line protocol is :"),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"<measurement>[,<tag_key>=<tag_value>[,<tag_key>=<tag_value>]] <field_key>=<field_value>[,<field_key>=<field_value>] [<timestamp>]")),(0,i.kt)("p",null,"where timestamp is in nanoseconds since epoch."),(0,i.kt)("p",null,"A typical service metric event as recorded by Druid's logging emitter is: ",(0,i.kt)("inlineCode",{parentName:"p"},'Event [{"feed":"metrics","timestamp":"2017-10-31T09:09:06.857Z","service":"druid/historical","host":"historical001:8083","version":"0.11.0-SNAPSHOT","metric":"query/cache/total/hits","value":34787256}]'),"."),(0,i.kt)("p",null,"This event is parsed into line protocol according to these rules:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"The measurement becomes druid_query since query is the first part of the metric."),(0,i.kt)("li",{parentName:"ul"},"The tags are service=druid/historical, hostname=historical001, metric=druid",(0,i.kt)("em",{parentName:"li"},"cache_total. (The metric tag is the middle part of the druid metric separated with ")," and preceded by druid_. Another example would be if an event has metric=query/time then there is no middle part and hence no metric tag)"),(0,i.kt)("li",{parentName:"ul"},"The field is druid_hits since this is the last part of the metric.")),(0,i.kt)("p",null,"This gives the following String which can be POSTed to InfluxDB: ",(0,i.kt)("inlineCode",{parentName:"p"},'"druid_query,service=druid/historical,hostname=historical001,metric=druid_cache_total druid_hits=34787256 1509440946857000000"')),(0,i.kt)("p",null,"The InfluxDB emitter has a white list of dimensions\nwhich will be added as a tag to the line protocol string if the metric has a dimension from the white list.\nThe value of the dimension is sanitized such that every occurrence of a dot or whitespace is replaced with a ",(0,i.kt)("inlineCode",{parentName:"p"},"_")," ."))}f.isMDXComponent=!0}}]);