{"id":3336,"date":"2021-03-06T18:11:53","date_gmt":"2021-03-06T18:11:53","guid":{"rendered":"https:\/\/wiki.thomasandsofia.com\/?p=3336"},"modified":"2021-03-08T02:40:26","modified_gmt":"2021-03-08T02:40:26","slug":"api-definitions-and-example-scripts","status":"publish","type":"post","link":"https:\/\/wiki.thomasandsofia.com\/?p=3336","title":{"rendered":"API Definitions and Example Scripts"},"content":{"rendered":"<p>API URL (endpoint)<\/p>\n<p>All data sent to http(s):\/\/api.zenoss.io<\/p>\n<h1>Definitions<\/h1>\n<p>&nbsp;<\/p>\n<h3>API-Key<\/h3>\n<ul>\n<li>Must first be generated from the Cloud UI &gt; API Clients &gt; Generate Key<\/li>\n<li>You must save this key once it is displayed.\u00a0 Zenoss does not store it.<\/li>\n<li>Key will be included with API requests and is used to:\n<ul>\n<li>Authenticate the request<\/li>\n<li>Assign the request to a Client<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h3>curl<\/h3>\n<pre>curl -s -S https:\/\/api.zenoss.io\/v1\/data-receiver\/models \\\r\n-H \"Content-type: application\/json\" \\\r\n-H \"zenoss-api-key: $(cat ~\/.zenoss.key)\" \\\r\n-X POST \\\r\n-d @simple-model.json<\/pre>\n<ul>\n<li>~\/.zenoss.key = text file with API-key<\/li>\n<li>simple-model.json: See Source Code<\/li>\n<\/ul>\n<pre>{\r\n  \"models\": [\r\n    {\r\n      \"timestamp\": $(date +%s000),\r\n      \"dimensions\": {\r\n        \"source\": \"$USER\",\r\n        \"source-type\": \"com.zenoss.training\"\r\n      },\r\n      \"metadataFields\": {\r\n        \"name\": \"${USER}-$(hostname-f)\"\r\n      }\r\n    }\r\n  ]\r\n}<\/pre>\n<h4>Options<\/h4>\n<ul>\n<li>-s: silent mode<\/li>\n<li>-S: Show errors, used with -s<\/li>\n<li>-H: header<\/li>\n<li>-X: request method, specifies the request method to use when communicating with the HTTP server.\n<ul>\n<li>POST, GET, etc.<\/li>\n<\/ul>\n<\/li>\n<li>-d: data.\u00a0 JSON string\n<ul>\n<li>@filename: reads JSON from the filename specified.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h3>dimensions<\/h3>\n<ul>\n<li>Required for both Model and Metric data<\/li>\n<li>Dimensions define which metrics belong to which entity\n<ul>\n<li>These can be completely user-defined as you wish<\/li>\n<\/ul>\n<\/li>\n<li>Entity dimensions are assigned in the Model<\/li>\n<li>Metric dimensions must exactly match the Model dimensions\n<ul>\n<li>Dimension fields should never change.\u00a0 If they do, then referring to a different entity.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<pre>...\r\n   \"dimensions\": {\r\n    \"source\": \"zennycorp\",\r\n    \"source-host\": \"web-01.zennycorp.com\",\r\n    \"source-type\": \"com.zenoss.training\"\r\n   },<\/pre>\n<p>&nbsp;<\/p>\n<h3>Entity<\/h3>\n<ul>\n<li>Any device, program, etc. that Metrics are associate or collected from.<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h3>HTTPie Utility<\/h3>\n<ul>\n<li>Install with Python PIP\n<ul>\n<li>pip install http https<\/li>\n<\/ul>\n<\/li>\n<li>Commands are <code>http<\/code> and <code>https<\/code><\/li>\n<li>Options\n<ul>\n<li>-b: body &#8211; print only the response body. Default behavior is to print the response headers and body<\/li>\n<li>URL: <code>http<\/code> or <code>https<\/code> are assumed by the command used.<\/li>\n<li>Name:Value : Additional HTTP headers<\/li>\n<\/ul>\n<\/li>\n<li>Defaults\n<ul>\n<li>GET if no request data<\/li>\n<li>POST if there is request data <code>&lt; filename<\/code> or `&lt; &#8220;JSON_STRING&#8221;<\/li>\n<li>Content-Type: &#8220;application\/json&#8221;<\/li>\n<li><code>:<\/code> : Shortcut for <code>localhost:<\/code><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<pre>https -b api.zenoss.io\/v1\/data-receiver\/models \\\r\n\"zenoss-api-key:$(cat ~\/.zenoss.key)\" \\\r\n&lt; simple-model.json<\/pre>\n<p>&nbsp;<\/p>\n<h3>jq<\/h3>\n<ul>\n<li>Linux CLI JSON processor, not installed by default<\/li>\n<li><code>jq<\/code> without options formats its input<\/li>\n<li><code>jq -c<\/code>\u00a0 outputs compact version without spaces and one object per line<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h3>metadataFields<\/h3>\n<ul>\n<li>Required Model field<\/li>\n<li>Contains &#8220;Optional&#8221; fields for storing metadata on a Model<\/li>\n<li>Should always include a &#8220;name&#8221;<\/li>\n<\/ul>\n<pre>{\r\n \"models\": [\r\n  ...,\r\n  \"metadataFields\": {\r\n   \"name\": \"web-01.zennycorp.com\"\r\n  }\r\n ]\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<h3>Metric<\/h3>\n<p><span style=\"color: #ff0000;\"><strong>You cannot send in metrics that are over 24 hours old!<\/strong><\/span><\/p>\n<ul>\n<li>A Metric is a key: value pair\n<ul>\n<li>metric = Metric Name<\/li>\n<li>value = Value of the metric<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<pre>{\r\n \"metrics: [\r\n  {\r\n   \"metric\": \"resource_load_avg_5min\",\r\n   \"timestamp: 1593883448000,\r\n   \"value\": 4.03,\r\n   \"dimensions\": {\r\n    \"source\": \"zennycorp\",\r\n    \"source-host\": \"web-01.zennycorp.com\",\r\n    \"source-type\": \"com.zenoss.training\"\r\n   }\r\n  }\r\n ]\r\n}<\/pre>\n<h4>Metrics Fields<\/h4>\n<p>Name of the metric<\/p>\n<table>\n<tbody>\n<tr>\n<th>Field Name<\/th>\n<th>Required<\/th>\n<th>Description<\/th>\n<\/tr>\n<tr>\n<td>timestamp<\/td>\n<th>Yes<\/th>\n<\/tr>\n<tr>\n<td>metric<\/td>\n<td>Yes<\/td>\n<td>Name of the metric<\/td>\n<\/tr>\n<tr>\n<td>value<\/td>\n<td>Yes<\/td>\n<td>Value of the metric<br \/>\nMust be numeric!<\/td>\n<\/tr>\n<tr>\n<td>dimensions<\/td>\n<td>Yes<\/td>\n<td><\/td>\n<\/tr>\n<tr>\n<td>metadataFields<\/td>\n<td>No<\/td>\n<td><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>&nbsp;<\/p>\n<h3>Model<\/h3>\n<ul>\n<li>Model defines an entity.<\/li>\n<li>One or more models may be defined in a single command.<\/li>\n<\/ul>\n<pre>{\r\n \"models: [\r\n  {\r\n   \"timestamp: 1593883448000,\r\n   \"dimensions\": {\r\n    \"source\": \"zennycorp\",\r\n    \"source-host\": \"web-01.zennycorp.com\",\r\n    \"source-type\": \"com.zenoss.training\"\r\n   },\r\n   \"metadataFields\": {\r\n    \"name\": \"web-01.zennycorp.com\"\r\n   }\r\n  }\r\n ]\r\n}<\/pre>\n<h4>Model Fields<\/h4>\n<table>\n<tbody>\n<tr>\n<th>Field Name<\/th>\n<th>Required<\/th>\n<th>Description<\/th>\n<\/tr>\n<tr>\n<td>timestamp<\/td>\n<td>Yes<\/td>\n<td><\/td>\n<\/tr>\n<tr>\n<td>dimensions<\/td>\n<td>Yes<\/td>\n<td><\/td>\n<\/tr>\n<tr>\n<td>metadataFields<\/td>\n<td>Yes<\/td>\n<td><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>&nbsp;<\/p>\n<h3>source<\/h3>\n<ul>\n<li>Sources are metric groups for dashboards<\/li>\n<li>Can be thought of as an instances of the source-type.\n<ul>\n<li>Example: Zenoss Cloud Kubernetes agen uses the cluster name as the source value.<\/li>\n<\/ul>\n<\/li>\n<li>Can be defined in either &#8220;dimension&#8221; or &#8220;metadataFields&#8221;\n<ul>\n<li>Use &#8220;metadataFields&#8221; if it is NOT required for uniqueness, i.e. to define it&#8217;s Entity.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h3>source-type<\/h3>\n<ul>\n<li>Optional<\/li>\n<li>Usually used to define the agent source the data is sent from\n<ul>\n<li>If the agent sending the data is Zenoss Cloud Kubernetes, you might use:\n<ul>\n<li>&#8220;source-type&#8221;: &#8220;zenoss.agent.kubernetes&#8221;<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<li>Can be defined in either &#8220;dimension&#8221; or &#8220;metadataFields&#8221;<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h3>timestamp<\/h3>\n<ul>\n<li>Required for both Model and Metric<\/li>\n<li>Milliseconds since Jan 1, 1970 at 00:00:00 UTC<\/li>\n<li>Linux commands\n<ul>\n<li>Current date time in seconds: <code>date +%s<\/code><\/li>\n<li>current date time in miliseconds: <code>date +%s000<\/code><\/li>\n<li><code>TIME_NOW_MS=$(date +%s000)<\/code><\/li>\n<li><code>TIME_NOW_MS=`date +%s000`<\/code><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<pre>{\r\n \"models: [\r\n  {\r\n   \"timestamp: 1593883448000,<\/pre>\n<p>&nbsp;<\/p>\n<h1>Source Code<\/h1>\n<h3>example.sh, example_new.sh<\/h3>\n<ul>\n<li>example_new.sh: Uncomment <code>#tee \/dev\/tty | \\<\/code><\/li>\n<\/ul>\n<pre>#! \/bin\/bash\r\nZUSER=\"troberts\"\r\nAPI_key=\"$(cat ~\/.zenoss.key)\"\r\nSOURCE=$ZUSER\r\nSOURCE_TYPE=com.zenoss.training\r\nHOST_NAME=$(hostname -f)\r\nTIME_NOW_MS=$(date +%s000)\r\nfunction data-receiver-api(){\r\n   # Takes 1 argument, 'models' or 'metrics'\r\n   local service=$1\r\n   #tee \/dev\/tty | \\\r\n   curl -s -S \\\r\n      \"https:\/\/api.zenoss.io\/v1\/data-receiver\/$service\" \\\r\n      -H \"content-type: application\/json\" \\\r\n      -H \"zenoss-api-key: $API_KEY\" \\\r\n      -X POST \\\r\n      -d @- | jq\r\n   echo\r\n}\r\necho \"Sending model for $SOURCE.\"\r\ndata-receiver-api models &lt;&lt; EoT\r\n{\r\n \"models\": [\r\n  {\r\n   \"timestamp\": $TIME_NOW_MS,\r\n   \"dimensions\": {\r\n    \"source\": \"$SOURCE\",\r\n    \"source-type\": \"$SOURCE_TYPE\"\r\n   },\r\n   \"metadataFields\": {\r\n    \"name\": \"$SOURCE-$HOST_NAME\"\r\n   }\r\n  }\r\n ]\r\n}\r\nEoT\r\n\r\necho \"Sending metric(s) for $SOURCE.\"\r\ndata-receiver-api metrics &lt;&lt; EoT\r\n{\r\n \"metrics\": [\r\n  {\r\n   \"metric\": \"random.number\",\r\n   \"timestamp\": $TIME_NOW_MS,\r\n   \"value\": $((RANDOM &amp; 127)),\r\n   \"dimensions\": {\r\n    \"source\": \"$SOURCE\",\r\n    \"source-type\": \"$SOURCE_TYPE\"\r\n   }\r\n  }\r\n ]\r\n}\r\nEoT\r\n<\/pre>\n<p>metric.json<\/p>\n<pre>{\"metrics\":[{\"metric\": \"random.number\",\"timestamp\": 1615068406000\"value\":17727,\"dimensions\":{\"source\":\"train-tr\",\"source-type\":\"com.zenoss.training\"}}]}\r\n<\/pre>\n<p>Pretty Version<\/p>\n<pre>{\r\n  \"metrics\": [\r\n    {\r\n      \"metric\": \"random.number\",\r\n      \"timestamp\": 1615068406000,\r\n      \"value\": 17727,\r\n      \"dimensions\": {\r\n        \"source\": \"train-tr\",\r\n        \"source-type\": \"com.zenoss.training\"\r\n      } \r\n    }\r\n  ]\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<h3>simple-json.model<\/h3>\n<pre>{\"models\":[{\"timestamp\": $(date +%s000),     \"dimensions\": {\r\n        \"source\": \"$USER\",\r\n        \"source-type\": \"com.zenoss.training\"\r\n      },\r\n      \"metadataFields\": {\r\n        \"name\": \"${USER}-$(hostname-f)\"\r\n      }\r\n    }\r\n  ]\r\n}<\/pre>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>API URL (endpoint) All data sent to http(s):\/\/api.zenoss.io Definitions &nbsp; API-Key Must first be generated from the Cloud UI &gt; API Clients &gt; Generate Key You must save this key once it is displayed.\u00a0 Zenoss does not store it. Key will be included with API requests and is used to: Authenticate the request Assign the ..<\/p>\n<div class=\"clear-fix\"><\/div>\n<p><a href=\"https:\/\/wiki.thomasandsofia.com\/?p=3336\" title=\"read more...\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[64,59],"tags":[],"class_list":["post-3336","post","type-post","status-publish","format-standard","hentry","category-streaming-data","category-zenoss"],"_links":{"self":[{"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=\/wp\/v2\/posts\/3336","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3336"}],"version-history":[{"count":21,"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=\/wp\/v2\/posts\/3336\/revisions"}],"predecessor-version":[{"id":3410,"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=\/wp\/v2\/posts\/3336\/revisions\/3410"}],"wp:attachment":[{"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3336"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3336"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3336"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}