Monitor Extensions (Beta)

Monitor Extensions are the most recently added extension type. They fill a very different functionality than the other extension types: they enable you to monitor your Agillic instance’s activities.

Monitor Extensions are in a beta phase. This means it is fully available on all instances, and is mature for production usage. In addition, you can expect feature expansions and improvements in future releases. Read our release notes, and this documentation to keep up to date! Feedback is welcome at product.feedback@agillic.com

Monitor Extensions have access to a 7-day history of your instance’s logs for a set of attributes relevant to the instance’s data ingress and egress, outbound communications, flow executions, and more. Instead of extension code affecting the recipients in your instance, in monitors you can write code to parse the instance’s data and verify your marketing/data-relevant operational statuses. The results can be delivered to a set of email addresses as HTML or provided as JSON requested via an API call (outbound HTTP calls to other endpoints are also supported). Results are classified as information or as errors.

Note that the word error in this Monitor Extension documentation refers to issues your monitor finds in the data, not an exception thrown in running the monitor. Read more details about the reporter, where errors are inserted.

There is no UI in the Agillic interface to view this extension type.

Here are some examples use cases which monitors can be written for, with the operational questions that can be answered:

Import Monitor

  • Did all files we expect get imported successfully?
  • Did any fail?
  • Did some never show up?
  • Is the row count of the file reasonable compared to previous files?

Flow Monitor

  • Did all expected flows run?
  • Is the recipient count entering the flow reasonable?
  • Are recipients being kicked, or failing at some point?

Outbound Communication Monitor

  • Are we sending a reasonable amount of this particular communication over the course of a day?

It’s also important to understand what Monitor Extensions cannot provide solutions for. They will not:

  • Get values of the Instance’s internal application logs, memory usage, or other server details
  • Do predictions of future campaigns
  • Provide status of incomplete, currently executing jobs
  • Show detailed Statistics of campaign performance (Like the Reporter and Activity Exports do)

Execution Method

The execution method for a Monitor Extension must be called monitor. This method does not have a return type, and the output of a Monitor Extension does not affect recipients, as other extension types do.

Execution Details

In addition to the monitor execution method, the monitor’s execution requires more details. These details are provided in the configuration function executionInfo, which has a response type of a JavaScript Map. We recommend keeping the setup a single statement, as shown in our example below, which utilizes all attributes.

Here is each allowed attribute described:

Attribute Description
urlTrigger Enables the execution of a Monitor Extension to be triggered by an endpoint protected with Basic Authentication using API Credentials: https://{instanceName}-prod.agillic.eu/api/v2/monitor/execute/{MonitorId} The results are delivered as a JSON Object derived from the reporter argument in the execution method.
responseCodeForError If reporter response contains errors, the response code will be as designated here. Otherwise, the monitor will return a 200.
async Allows for asynchronous execution, so the monitor can be triggered, providing an immmediate 202 response, while the monitor runs. Calling the same the same triggering url will either return 202 if it is still running, a 200 if the monitor ran with no errors, or the urlTrigger.responseCodeForError value if there was an error present.
cacheInMinutes Duration of time the monitor's response is cached, in minutes. The minimum and default time is 10 minutes, and a monitor cannot be run more than once every 10 minutes.
scheduled Enables the execution of a Monitor Extension to be scheduled, and deliver the results by email, with the results accessible by URL.
alertEmails List of emails monitor should send alert emails to, containing HTML describing of reporter.error. Can be empty, but then no email is sent when an error details are found.
statusEmails List of emails monitor should send status emails to, containing HTML describing reporter.info details. Can be empty, but then no email is sent when information details are found.
hours List of hours when monitor is scheduled to be run. Monitor results are evaluated 5 minutes after the hour start, and depending on the contents of the reporter argument, send emails to the statusEmails or alertEmails list.
urlExposed Enables the fetching of the JSON results of the more recent scheduled run, via an endpoint protected with Basic Authentication using API Credentials: https://{instanceName}-prod.agillic.eu/api/v2/monitor/result/{MonitorId} The results are delivered as a JSON Object derived from the reporter argument in the execution method.

The Email lists do not have to be filled out if you would rather the monitor results to your own endpoint. See an example here: Notify Endpoint

Arguments

The input arguments for Monitor Extensions are unique to the type, but in general are readable/writable in a similar fashion to the other more standard input arguments.

  • activity: This is a read-only variable which contains the data describing the Instance's last 7 days of logs.
  • reporter: This variable is where results are written, to inform the relevant stakeholders of general information, or raise an alarm if necessary.

Details on activity

Reading activity object

Imports
Attribute imports
Array with each entry containing a import file log. Import files is still being processed are not included.
Object Details
            
                [
                    {
                        "name": "string",
                        "start": "timestamp",
                        "end": "timestamp",
                        "success": "boolean",
                        "lines": "number"
                    },
                    ...
                ]
            
        
Iteration & Reading Example
            
                activity.imports.forEach(function(file) {
                    //The import file's name
                    var fileName = file.name;
                    //Timestamp of import start time
                    var importStartTime = file.start;
                    //Timestamp of import completion time
                    var importEndTime = file.end;
                    //Boolean of import status
                    var importStatus = file.success;
                    //Count of rows imported by the file
                    var importEndTime = file.lines;
                  }
            
        
Executions
Attribute executions
Array with each entry containing current status of a scheduled flow execution. Flow executions of 0 recipients and trigger flows are not included.
Object Details
            
                [
                {
                  "flow": "string",
                  "targetGroup": "string",
                  "total": "number",
                  "waitForActivity": "number",
                  "waitForTime": "number",
                  "interrupted": "number",
                  "timeout": "number",
                  "kickOut": "number",
                  "failed": "number",
                  "done": "number",
                  "start": "timestamp",
                  "lastActivity": "timestamp"
                },
                ...
              ]
            
        
Iteration & Reading Example
            
                activity.executions.forEach(function(exec){
                    //Name of flow
                    var flowName = exec.flow
                    //Time flow began
                    var flowStart = exec.start
                    //Target group name in flow
                    var flowTG = exec.targetGroup
                    //Total recipients entering flow
                    var flowTotal = exec.total
                    //Total recipients currently in WFA step
                    var flowWFA = exec.waitForActivity
                    //Total recipients currently in WFT step
                    var flowWFT = exec.waitForTime
                    //Total recipients interrupted in flow
                    var flowInt = exec.interrupted
                    //Total recipients kicked via timeout
                    var flowTimeout = exec.timeout
                    //Total recipients kicked manually or via pause
                    var flowKick = exec.kickOut
                    //Total recipients that have failed in a step
                    var flowFailed = exec.failed
                    //Total recipients exited from flow execution
                    var flowDone = exec.done
                    //Last time a recipient has moved steps in the flow
                    var flowLastAct = exec.lastActivity
                  }
            
        
Uploads
Attribute uploads
Array with each entry containing Export Flow generated files, uploaded to external services using an Export Profile
Object Details
            
                [
                {
                  "filename": "string",
                  "uploadDate": "timestamp",
                  "success": "boolean"
                },
                ...
              ]
            
        
Iteration & Reading Example
            
                activity.uploads.forEach(function(upload){
                    //The upload file's name
                    var uploadName = upload.filename;
                    //The timestamp the file was uploaded
                    var uploadTime = upload.uploadDate;
                    //Boolean describing upload status
                    var uploadStatus = upload.success;
                  }
            
        
Activity Exports
Attribute activityExports
Array with each entry containing generated and exported(if relevant) Activity Export Files.
Object Details
            
                [
                {
                  "name": "string",
                  "started": "timestamp",
                  "success": "boolean",
                  "uploadSuccess": "boolean",
                  "lines": {
                    "EMAIL": "number",
                    "SMS": "number",
                    "EVENT": "number",
                    "TRANSACTIONAL_EMAIL": "number",
                    "INBOUND_SMS": "number",
                    "PUSH_NOTIFICATION": "number",
                    "PROMOTION": "number",
                    "PRINT": "number",
                    "PAGE": "number",
                    "GOOGLE_CM": "number",
                    "FACEBOOK_CA": "number",
                    "ADFORM": "number"
                  }
                },
                ...
              ]
            
        
Iteration & Reading Example
            
                activity.activityExports.forEach(function(actExp) {
                    //The act. export's(AE's) file name
                    var actExpName = actExp.name;
                    //The AE's start time
                    var actExpStart = actExp.started;
                    //The AE's completion status
                    var actExpStatus = actExp.success;
                    //The AE's upload status
                    var actExpUploadStatus = actExp.uploadSuccess;
                    //Object with count of each exported channel's line count
                    var actExpLines = actExp.lines;
                  }
            
        
Outbound
Attribute outbound
Array with each entry containing all types of outbound activity with day granularity.
Object Details
            
                [
                {
                  "name": "string",
                  "type": "string",
                  "date": "date",
                  "actionCount": {
                    "success": "number",
                    "error": "number",
                    "hard_bounce": "number"
                  }
                },
                ...
              ]
            
        
Iteration & Reading Example
            
                activity.outbound.forEach(function(comm){
                    //The communication's name
                    var commName = comm.name;
                    //The comm's channel type
                    var comType = comm.type;
                    //The comm's sendout date
                    var commStart = comm.date;
                    //Object describing total count of success, error, 
                    //and hard_bounce of this comm, for the date provided. 
                    var commCount = comm.actionCount;
                  }
            
        

Activities where nothing occurs are not logged in the activity argument. For example, flow executions with 0 recipients, outbound communications with 0 sent or errored: all are not present in these logs.

Details on reporter

Writing to reporter object

The reporter input argument provides a standardized way to mark results of the Monitor extension as errors, or just information. Both errors and information support 2 different ways to store information, with a flag or increment, as shown below:

Attribute Example Output
reporter.error.flag

Any attributes written to this entry point will create a flag which will be classified as an error for the provided primary headline, and secondary headline.

reporter.error.flag("Files not Imported","File1");
                    
                        // JSON
                        {
                          "created": "09-09-2020 15:22",
                          "errorCode": 400,
                          "errors": {
                            "flag": {
                              "Files not Imported": {
                                "File1": true
                              }
                            },
                            "counter": {
                              "Rows Missing": {
                                "rows": -128
                              }
                            }
                          },
                          "info": {
                            "flag": {
                              "Files Imported": {
                                "File2": true
                              }
                            },
                            "counter": {
                              "File Row Count": {
                                "File2": 1024
                              }
                            }
                          }
                        }
                    
                
reporter.error.inc

Any attributes written to this entry point will increment a counter which will be classified as an error for the provided primary headline, and secondary headline.

reporter.error.inc("Rows Missing","rows",-128);
reporter.info.flag

Any attributes written to this entry point will will create a flag which will be classified as information for the provided primary headline, and secondary headline.

reporter.info.flag("Files Imported","File2");
                    
                        HTML
    
                        In Error Email:
                        Subject Line: Monitor found error: instance-prod
                        Files not Imported
                        
                            File1
                        
                        Rows Missing
                        
                            rows : -128
                        
                        In Status Email:
                        Subject Line: Monitor report: instance-prod
    
                        File Row Count
                        
                            File2 : 1024
                        
                        Files Imported
                        
                            File2
                    
                
reporter.info.inc

Any attributes written to this entry point will increment a counter which will be classified as information for the provided primary headline, and secondary headline.

reporter.info.inc("File Row Count","File2",1024);

Reading reporter object

In some cases, you may want to read the reporter as a JSON Object. You can achieve this by calling the reporter with the jsonString method, and parsing it as a JSON Object:

var reporterJSON = JSON.parse(reporter.jsonString);

//now you can access it as a JSON Object 
var reporterJSONError = reporterJSON.errors;
var reporterJSONInfo = reporterJSON.info;

The main use-case that you may want to use the reporter as a JSON Object, is if you wanted to send the results of a monitor to an endpoint. See below for an example implementation of a this setup.

Notify an Endpoint

If you are using a URL triggered monitor with the asynchronous option, or just want a scheduled monitor which also sends results to a particular endpoint, you can use our Http Helper to send an HTTP request. An example implementation could look like:

This approach works for both scheduled and triggered executions, as all code is executed in order.

Examples

You can view these example monitor extensions in the Examples section: