{"_id":"57fcc4870312b20e00ac64eb","user":"547d27d12eaee50800ed1157","__v":0,"version":{"_id":"57fcc4860312b20e00ac64c0","project":"5435687035740020002a1c04","__v":1,"createdAt":"2016-10-11T10:52:54.637Z","releaseDate":"2016-10-11T10:52:54.637Z","categories":["57fcc4860312b20e00ac64c1","57fcc4860312b20e00ac64c2","57fcc4860312b20e00ac64c3","57fcc4860312b20e00ac64c4","57fcc4860312b20e00ac64c5","57fcc4860312b20e00ac64c6","57fcc4860312b20e00ac64c7","57fcc4860312b20e00ac64c8","57fcc4860312b20e00ac64c9","57fcc4860312b20e00ac64ca","57fcc4860312b20e00ac64cb"],"is_deprecated":false,"is_hidden":false,"is_beta":false,"is_stable":true,"codename":"[APP-1265], [APP-1035]","version_clean":"5.2.0","version":"5.2"},"parentDoc":null,"project":"5435687035740020002a1c04","category":{"_id":"57fcc4860312b20e00ac64c7","__v":0,"version":"57fcc4860312b20e00ac64c0","project":"5435687035740020002a1c04","sync":{"url":"","isSync":false},"reference":false,"createdAt":"2014-11-25T22:05:12.981Z","from_sync":false,"order":6,"slug":"agent-integration","title":"Data Agent"},"updates":[],"next":{"pages":[],"description":""},"createdAt":"2015-02-02T01:59:09.664Z","link_external":false,"link_url":"","githubsync":"","sync_unique":"","hidden":false,"api":{"results":{"codes":[]},"settings":"","auth":"required","params":[],"url":""},"isReference":false,"order":5,"body":"The Agent can run continuously and execute external processes at deterministic, scheduled intervals. The output taken from those processes is then sent on to the TelemetryTV API for processing as a flow update.\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/tkKcXbGtQ9Wd5BZavE5Q_exec.png\",\n        \"exec.png\",\n        \"993\",\n        \"210\",\n        \"#1097f8\",\n        \"\"\n      ]\n    }\n  ]\n}\n[/block]\nThe nature of these executables is entirely up to you; this means that you can write code that extracts data from your internal systems using the language and tooling already at your disposal, rather than having to learn a new language or use tools that are limited in scope and functionality.\n\n[block:callout]\n{\n  \"type\": \"info\",\n  \"title\": \"Write in any Language\",\n  \"body\": \"The samples below are written in JavaScript and intended to run with Node.js, but this is for illustration purposes only; you are free to write your executables in any language (or using any other tool that can output the proper JSON data).\"\n}\n[/block]\n# Writing Agent Executables\n\nAs mentioned above, the external process that the Agent executes as part of a flow update could be written in any language (or based on any external tool), as long as it outputs information that the Agent can interpret and send on to the TelemetryTV API.\n\n## Updating a Flow\n\nThe simplest output of an executable is a JSON structure that contains changes you want to make to the flow. For example, an executable that only wants to change the  `value` property of a number flow could work like this:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"#!/usr/bin/env node\\n\\n'use strict';\\n\\nvar metrics = { number: { value: 123 }};\\nconsole.log(JSON.stringify(metrics));\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\nWhen executed, this script simply outputs the text `{\"number\":{\"value\":123}}`—a valid JSON structure that sets the number value to 123.\n\nWhen the script is finished running, the Agent interprets this kind of output as a HTTP PATCH operation that, once sent to the TelemetryTV API, will result in the root-level properties specified in the result being used to replace the then-current contents of the flow. In this particular example, therefore, the script is requesting that only the `value` property of the flow be changed, while everything else will remain the same.\n\n## Replacing a Flow\n\nWhile the HTTP PATCH approach gives your external processes the flexibility of making changes to flows without interfering with their contents (which, after all, may be changed asynchronously by other agents, or by designers through the TelemetryTV website), it may be desirable to completely replace the contents of a flow instead.\n\nThe Agent supports this scenario by allowing external process to prefix their output with the string `\"REPLACE\\n\"`. For example:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"#!/usr/bin/env node\\n\\n'use strict';\\n\\nvar metrics = { color: 'red', value : 123 };\\n\\nconsole.log('REPLACE');\\nconsole.log(JSON.stringify(metrics));\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\nIn this case, the Agent will perform a PUT operation against the API, instead of a PATCH.\n\n## Using JSON Patch\n\nFor an even finer degree of control over the Agent's operations, external processes can output a [JSON Patch](http://jsonpatch.com) package. This format, which is widely support in most programming environment, allows you to perform deep-replacement operations against properties of a flow with an arbitrary level of nesting; for example, you can use this to replace individual values in a graph widget's data series:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"#!/usr/bin/env node\\n\\n'use strict';\\n\\nvar metrics = [\\n\\t{\\n  \\top: 'replace',\\n    path: '/series/0/values/11',\\n    value: 13392.29\\n  }\\n];\\n\\nconsole.log('JSONPATCH');\\nconsole.log(JSON.stringify(metrics));\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\nAs you can see, in this case, the script's output is prefixed with the string `\"JSONPATCH\\n\"`.\n\n## Error reporting\n\nThe Agent automatically detect error conditions from executables by examining their exit value. A non-zero result, alongside the contents of stderr, is reported as an error in the Agent's log.\n\nIn addition, the agent Will also report any errors it detects to the API. When this happens, the errors will be added to your account log, and they will be visible on all the boards on which the affected flow resides.\n[block:callout]\n{\n  \"type\": \"info\",\n  \"body\": \"The Agent _always_ waits for the external process to exit before interpreting its output and sending it to the TelemetryTV API. Therefore, your executables must output data and exit as quickly as practicable. Streaming-like operations in which your executables output more than one update are not supported by the Agent.\",\n  \"title\": \"No support for streaming\"\n}\n[/block]\n# Example\n\nPlease see the [Database executable example](doc:querying-a-database) for more code on how you'd install configure and write an executable program.","excerpt":"","slug":"executables","type":"basic","title":"Executables"}
The Agent can run continuously and execute external processes at deterministic, scheduled intervals. The output taken from those processes is then sent on to the TelemetryTV API for processing as a flow update. [block:image] { "images": [ { "image": [ "https://files.readme.io/tkKcXbGtQ9Wd5BZavE5Q_exec.png", "exec.png", "993", "210", "#1097f8", "" ] } ] } [/block] The nature of these executables is entirely up to you; this means that you can write code that extracts data from your internal systems using the language and tooling already at your disposal, rather than having to learn a new language or use tools that are limited in scope and functionality. [block:callout] { "type": "info", "title": "Write in any Language", "body": "The samples below are written in JavaScript and intended to run with Node.js, but this is for illustration purposes only; you are free to write your executables in any language (or using any other tool that can output the proper JSON data)." } [/block] # Writing Agent Executables As mentioned above, the external process that the Agent executes as part of a flow update could be written in any language (or based on any external tool), as long as it outputs information that the Agent can interpret and send on to the TelemetryTV API. ## Updating a Flow The simplest output of an executable is a JSON structure that contains changes you want to make to the flow. For example, an executable that only wants to change the `value` property of a number flow could work like this: [block:code] { "codes": [ { "code": "#!/usr/bin/env node\n\n'use strict';\n\nvar metrics = { number: { value: 123 }};\nconsole.log(JSON.stringify(metrics));", "language": "javascript" } ] } [/block] When executed, this script simply outputs the text `{"number":{"value":123}}`—a valid JSON structure that sets the number value to 123. When the script is finished running, the Agent interprets this kind of output as a HTTP PATCH operation that, once sent to the TelemetryTV API, will result in the root-level properties specified in the result being used to replace the then-current contents of the flow. In this particular example, therefore, the script is requesting that only the `value` property of the flow be changed, while everything else will remain the same. ## Replacing a Flow While the HTTP PATCH approach gives your external processes the flexibility of making changes to flows without interfering with their contents (which, after all, may be changed asynchronously by other agents, or by designers through the TelemetryTV website), it may be desirable to completely replace the contents of a flow instead. The Agent supports this scenario by allowing external process to prefix their output with the string `"REPLACE\n"`. For example: [block:code] { "codes": [ { "code": "#!/usr/bin/env node\n\n'use strict';\n\nvar metrics = { color: 'red', value : 123 };\n\nconsole.log('REPLACE');\nconsole.log(JSON.stringify(metrics));", "language": "javascript" } ] } [/block] In this case, the Agent will perform a PUT operation against the API, instead of a PATCH. ## Using JSON Patch For an even finer degree of control over the Agent's operations, external processes can output a [JSON Patch](http://jsonpatch.com) package. This format, which is widely support in most programming environment, allows you to perform deep-replacement operations against properties of a flow with an arbitrary level of nesting; for example, you can use this to replace individual values in a graph widget's data series: [block:code] { "codes": [ { "code": "#!/usr/bin/env node\n\n'use strict';\n\nvar metrics = [\n\t{\n \top: 'replace',\n path: '/series/0/values/11',\n value: 13392.29\n }\n];\n\nconsole.log('JSONPATCH');\nconsole.log(JSON.stringify(metrics));", "language": "javascript" } ] } [/block] As you can see, in this case, the script's output is prefixed with the string `"JSONPATCH\n"`. ## Error reporting The Agent automatically detect error conditions from executables by examining their exit value. A non-zero result, alongside the contents of stderr, is reported as an error in the Agent's log. In addition, the agent Will also report any errors it detects to the API. When this happens, the errors will be added to your account log, and they will be visible on all the boards on which the affected flow resides. [block:callout] { "type": "info", "body": "The Agent _always_ waits for the external process to exit before interpreting its output and sending it to the TelemetryTV API. Therefore, your executables must output data and exit as quickly as practicable. Streaming-like operations in which your executables output more than one update are not supported by the Agent.", "title": "No support for streaming" } [/block] # Example Please see the [Database executable example](doc:querying-a-database) for more code on how you'd install configure and write an executable program.