# Control-M server by HTTP ## Overview This template is designed to get metrics from the Control-M server using the Control-M Automation API with HTTP agent. This template monitors server statistics, discovers jobs and agents using Low Level Discovery. To use this template, macros {$API.TOKEN}, {$API.URI.ENDPOINT}, and {$SERVER.NAME} need to be set. ## Requirements Zabbix version: 7.0 and higher. ## Tested versions This template has been tested on: - Control-M 9.21.0 ## Configuration > Zabbix should be configured according to the instructions in the [Templates out of the box](https://www.zabbix.com/documentation/7.0/manual/config/templates_out_of_the_box) section. ## Setup This template is primarily intended for using in conjunction with the `Control-M enterprise manager by HTTP` template in order to create host prototypes. It monitors: * server statistics; * discovers jobs using Low Level Discovery; * discovers agents using Low Level Discovery. However, if you wish to monitor the Control-M server separately with this template, you must set the following macros: **{$API.TOKEN}**, **{$API.URI.ENDPOINT}**, and **{$SERVER.NAME}**. To access the `{$API.TOKEN}` macro, use one of the following interfaces: > [Control-M WEB user interface](https://documents.bmc.com/supportu/controlm-saas/en-US/Documentation/Creating_an_API_Token.htm); > [Control-M command line interface tool CTM](https://docs.bmc.com/docs/saas-api/authentication-service-941879068.html). `{$API.URI.ENDPOINT}` - is the Control-M Automation API endpoint for the API requests, including your server IP, or DNS address, the Automation API port and path. For example, `https://monitored.controlm.instance:8443/automation-api`. `{$SERVER.NAME}` - is the name of the Control-M server to be monitored. ### Macros used |Name|Description|Default| |----|-----------|-------| |{$SERVER.NAME}|

The name of the Control-M server.

|``| |{$API.URI.ENDPOINT}|

The API endpoint is a URI - for example, `https://monitored.controlm.instance:8443/automation-api`.

|``| |{$API.TOKEN}|

A token to use for API connections.

|``| ### Items |Name|Description|Type|Key and additional info| |----|-----------|----|-----------------------| |Control-M: Get Control-M server stats|

Gets the statistics of the server.

|HTTP agent|controlm.server.stats

**Preprocessing**

  • JSON Path: `$.[?(@.name == '{$SERVER.NAME}')].first()`

    ⛔️Custom on fail: Set error to: `Could not get server stats.`

| |Control-M: Get jobs|

Gets the status of jobs.

|HTTP agent|controlm.jobs| |Control-M: Get agents|

Gets agents for the server.

|HTTP agent|controlm.agents| |Control-M: Jobs statistics|

Gets the statistics of jobs.

|Dependent item|controlm.jobs.statistics

**Preprocessing**

  • JSON Path: `$.['returned', 'total']`

| |Control-M: Jobs returned|

Gets the count of returned jobs.

|Dependent item|controlm.jobs.statistics.returned

**Preprocessing**

  • JSON Path: `$.[0]`

  • Discard unchanged with heartbeat: `1h`

| |Control-M: Jobs total|

Gets the count of total jobs.

|Dependent item|controlm.jobs.statistics.total

**Preprocessing**

  • JSON Path: `$.[1]`

  • Discard unchanged with heartbeat: `1h`

| |Control-M: Server state|

Gets the metric of the server state.

|Dependent item|server.state

**Preprocessing**

  • JSON Path: `$.state`

    ⛔️Custom on fail: Set error to: `Could not get server state.`

  • JavaScript: `The text is too long. Please see the template.`

  • Discard unchanged with heartbeat: `1h`

| |Control-M: Server message|

Gets the metric of the server message.

|Dependent item|server.message

**Preprocessing**

  • JSON Path: `$.message`

    ⛔️Custom on fail: Set error to: `Could not get server message.`

  • Discard unchanged with heartbeat: `1h`

| |Control-M: Server version|

Gets the metric of the server version.

|Dependent item|server.version

**Preprocessing**

  • JSON Path: `$.version`

    ⛔️Custom on fail: Set error to: `Could not get server version.`

  • Discard unchanged with heartbeat: `1h`

| ### Triggers |Name|Description|Expression|Severity|Dependencies and additional info| |----|-----------|----------|--------|--------------------------------| |Control-M: Server is down|

The server is down.

|`last(/Control-M server by HTTP/server.state)=0 or last(/Control-M server by HTTP/server.state)=10`|High|| |Control-M: Server disconnected|

The server is disconnected.

|`last(/Control-M server by HTTP/server.message,#1)="Disconnected"`|High|| |Control-M: Server error|

The server has encountered an error.

|`last(/Control-M server by HTTP/server.message,#1)<>"Connected" and last(/Control-M server by HTTP/server.message,#1)<>"Disconnected" and last(/Control-M server by HTTP/server.message,#1)<>""`|High|| |Control-M: Server version has changed|

The server version has changed. Acknowledge to close the problem manually.

|`last(/Control-M server by HTTP/server.version,#1)<>last(/Control-M server by HTTP/server.version,#2) and length(last(/Control-M server by HTTP/server.version))>0`|Info|**Manual close**: Yes| ### LLD rule Jobs discovery |Name|Description|Type|Key and additional info| |----|-----------|----|-----------------------| |Jobs discovery|

Discovers jobs on the server.

|Dependent item|controlm.jobs.discovery

**Preprocessing**

  • JSON Path: `$.statuses`

    ⛔️Custom on fail: Set value to: `[]`

  • Discard unchanged with heartbeat: `1h`

| ### Item prototypes for Jobs discovery |Name|Description|Type|Key and additional info| |----|-----------|----|-----------------------| |Job [{#JOB.ID}]: stats|

Gets the statistics of a job.

|Dependent item|job.stats['{#JOB.ID}']

**Preprocessing**

  • JSON Path: `$.statuses.[?(@.jobId == '{#JOB.ID}')].first()`

    ⛔️Custom on fail: Discard value

| |Job [{#JOB.ID}]: status|

Gets the status of a job.

|Dependent item|job.status['{#JOB.ID}']

**Preprocessing**

  • JSON Path: `$.status`

  • JavaScript: `The text is too long. Please see the template.`

  • Discard unchanged with heartbeat: `1h`

| |Job [{#JOB.ID}]: number of runs|

Gets the number of runs for a job.

|Dependent item|job.numberOfRuns['{#JOB.ID}']

**Preprocessing**

  • JSON Path: `$.numberOfRuns`

  • Discard unchanged with heartbeat: `1h`

| |Job [{#JOB.ID}]: type|

Gets the job type.

|Dependent item|job.type['{#JOB.ID}']

**Preprocessing**

  • JSON Path: `$.type`

  • JavaScript: `The text is too long. Please see the template.`

  • Discard unchanged with heartbeat: `1h`

| |Job [{#JOB.ID}]: held status|

Gets the held status of a job.

|Dependent item|job.held['{#JOB.ID}']

**Preprocessing**

  • JSON Path: `$.held`

  • JavaScript: `The text is too long. Please see the template.`

| ### Trigger prototypes for Jobs discovery |Name|Description|Expression|Severity|Dependencies and additional info| |----|-----------|----------|--------|--------------------------------| |Job [{#JOB.ID}]: status [{ITEM.VALUE}]|

The job has encountered an issue.

|`last(/Control-M server by HTTP/job.status['{#JOB.ID}'],#1)=1 or last(/Control-M server by HTTP/job.status['{#JOB.ID}'],#1)=10`|Warning|**Manual close**: Yes| ### LLD rule Agent discovery |Name|Description|Type|Key and additional info| |----|-----------|----|-----------------------| |Agent discovery|

Discovers agents on the server.

|Dependent item|controlm.agent.discovery

**Preprocessing**

  • JSON Path: `$.agents`

    ⛔️Custom on fail: Set value to: `[]`

  • Discard unchanged with heartbeat: `1h`

| ### Item prototypes for Agent discovery |Name|Description|Type|Key and additional info| |----|-----------|----|-----------------------| |Agent [{#AGENT.NAME}]: stats|

Gets the statistics of an agent.

|Dependent item|agent.stats['{#AGENT.NAME}']

**Preprocessing**

  • JSON Path: `$.agents.[?(@.nodeid == '{#AGENT.NAME}')].first()`

    ⛔️Custom on fail: Discard value

| |Agent [{#AGENT.NAME}]: status|

Gets the status of an agent.

|Dependent item|agent.status['{#AGENT.NAME}']

**Preprocessing**

  • JSON Path: `$.status`

  • JavaScript: `The text is too long. Please see the template.`

  • Discard unchanged with heartbeat: `1h`

| |Agent [{#AGENT.NAME}]: version|

Gets the version number of an agent.

|Dependent item|agent.version['{#AGENT.NAME}']

**Preprocessing**

  • JSON Path: `$.version`

    ⛔️Custom on fail: Set value to: `Unknown`

  • Discard unchanged with heartbeat: `1h`

| ### Trigger prototypes for Agent discovery |Name|Description|Expression|Severity|Dependencies and additional info| |----|-----------|----------|--------|--------------------------------| |Agent [{#AGENT.NAME}]: status [{ITEM.VALUE}]|

The agent has encountered an issue.

|`last(/Control-M server by HTTP/agent.status['{#AGENT.NAME}'],#1)=1 or last(/Control-M server by HTTP/agent.status['{#AGENT.NAME}'],#1)=10`|Average|**Manual close**: Yes| |Agent [{#AGENT.NAME}}: status disabled|

The agent is disabled.

|`last(/Control-M server by HTTP/agent.status['{#AGENT.NAME}'],#1)=2 or last(/Control-M server by HTTP/agent.status['{#AGENT.NAME}'],#1)=3`|Info|**Manual close**: Yes| |Agent [{#AGENT.NAME}]: version has changed|

The agent version has changed. Acknowledge to close the problem manually.

|`last(/Control-M server by HTTP/agent.version['{#AGENT.NAME}'],#1)<>last(/Control-M server by HTTP/agent.version['{#AGENT.NAME}'],#2)`|Info|**Manual close**: Yes| |Agent [{#AGENT.NAME}]: unknown version|

The agent version is unknown.

|`last(/Control-M server by HTTP/agent.version['{#AGENT.NAME}'],#1)="Unknown"`|Warning|**Manual close**: Yes| # Control-M enterprise manager by HTTP ## Overview The template to monitor Control-M by Zabbix that work without any external scripts. ## Requirements Zabbix version: 7.0 and higher. ## Tested versions This template has been tested on: - Control-M 9.21.0 ## Configuration > Zabbix should be configured according to the instructions in the [Templates out of the box](https://www.zabbix.com/documentation/7.0/manual/config/templates_out_of_the_box) section. ## Setup This template is intended to be used on Control-M Enterprise Manager instances. It monitors: * active SLA services; * discovers Control-M servers using Low Level Discovery; * creates host prototypes for discovered servers with the `Control-M server by HTTP` template. To use this template, you must set macros: **{$API.TOKEN}** and **{$API.URI.ENDPOINT}**. To access the API token, use one of the following Control-M interfaces: > [Control-M WEB user interface](https://documents.bmc.com/supportu/controlm-saas/en-US/Documentation/Creating_an_API_Token.htm); > [Control-M command line interface tool CTM](https://docs.bmc.com/docs/saas-api/authentication-service-941879068.html). `{$API.URI.ENDPOINT}` - is the Control-M Automation API endpoint for the API requests, including your server IP, or DNS address, Automation API port and path. For example, `https://monitored.controlm.instance:8443/automation-api`. ### Macros used |Name|Description|Default| |----|-----------|-------| |{$API.URI.ENDPOINT}|

The API endpoint is a URI - for example, `https://monitored.controlm.instance:8443/automation-api`.

|``| |{$API.TOKEN}|

A token to use for API connections.

|``| ### Items |Name|Description|Type|Key and additional info| |----|-----------|----|-----------------------| |Control-M: Get Control-M servers|

Gets a list of servers.

|HTTP agent|controlm.servers| |Control-M: Get SLA services|

Gets all the SLA active services.

|HTTP agent|controlm.services| ### LLD rule Server discovery |Name|Description|Type|Key and additional info| |----|-----------|----|-----------------------| |Server discovery|

Discovers the Control-M servers.

|Dependent item|controlm.server.discovery

**Preprocessing**

  • Discard unchanged with heartbeat: `2h`

| ### LLD rule SLA services discovery |Name|Description|Type|Key and additional info| |----|-----------|----|-----------------------| |SLA services discovery|

Discovers the SLA services in the Control-M environment.

|Dependent item|controlm.services.discovery

**Preprocessing**

  • JSON Path: `$.activeServices`

    ⛔️Custom on fail: Set value to: `[]`

  • Discard unchanged with heartbeat: `1h`

| ### Item prototypes for SLA services discovery |Name|Description|Type|Key and additional info| |----|-----------|----|-----------------------| |Service [{#SERVICE.NAME}, {#SERVICE.JOB}]: stats|

Gets the service statistics.

|Dependent item|service.stats['{#SERVICE.NAME}','{#SERVICE.JOB}']

**Preprocessing**

  • JSON Path: `$.activeServices.[?(@.serviceName == '{#SERVICE.NAME}')]`

    ⛔️Custom on fail: Discard value

  • JSON Path: `$.[?(@.serviceJob == '{#SERVICE.JOB}')].first()`

    ⛔️Custom on fail: Discard value

| |Service [{#SERVICE.NAME}, {#SERVICE.JOB}]: status|

Gets the service status.

|Dependent item|service.status['{#SERVICE.NAME}','{#SERVICE.JOB}']

**Preprocessing**

  • JSON Path: `$.status`

  • JavaScript: `The text is too long. Please see the template.`

  • Discard unchanged with heartbeat: `1h`

| |Service [{#SERVICE.NAME}, {#SERVICE.JOB}]: jobs 'executed'|

Gets the number of jobs in the state - `executed`.

|Dependent item|service.jobs.status['{#SERVICE.NAME}','{#SERVICE.JOB}',executed]

**Preprocessing**

  • JSON Path: `$.statusByJobs.executed`

  • Discard unchanged with heartbeat: `1h`

| |Service [{#SERVICE.NAME}, {#SERVICE.JOB}]: jobs 'waitCondition'|

Gets the number of jobs in the state - `waitCondition`.

|Dependent item|service.jobs.status['{#SERVICE.NAME}','{#SERVICE.JOB}',waitCondition]

**Preprocessing**

  • JSON Path: `$.statusByJobs.waitCondition`

  • Discard unchanged with heartbeat: `1h`

| |Service [{#SERVICE.NAME}, {#SERVICE.JOB}]: jobs 'waitResource'|

Gets the number of jobs in the state - `waitResource`.

|Dependent item|service.jobs.status['{#SERVICE.NAME}','{#SERVICE.JOB}',waitResource]

**Preprocessing**

  • JSON Path: `$.statusByJobs.waitResource`

  • Discard unchanged with heartbeat: `1h`

| |Service [{#SERVICE.NAME}, {#SERVICE.JOB}]: jobs 'waitHost'|

Gets the number of jobs in the state - `waitHost`.

|Dependent item|service.jobs.status['{#SERVICE.NAME}','{#SERVICE.JOB}',waitHost]

**Preprocessing**

  • JSON Path: `$.statusByJobs.waitHost`

  • Discard unchanged with heartbeat: `1h`

| |Service [{#SERVICE.NAME}, {#SERVICE.JOB}]: jobs 'waitWorkload'|

Gets the number of jobs in the state - `waitWorkload`.

|Dependent item|service.jobs.status['{#SERVICE.NAME}','{#SERVICE.JOB}',waitWorkload]

**Preprocessing**

  • JSON Path: `$.statusByJobs.waitWorkload`

  • Discard unchanged with heartbeat: `1h`

| |Service [{#SERVICE.NAME}, {#SERVICE.JOB}]: jobs 'completed'|

Gets the number of jobs in the state - `completed`.

|Dependent item|service.jobs.status['{#SERVICE.NAME}','{#SERVICE.JOB}',completed]

**Preprocessing**

  • JSON Path: `$.statusByJobs.completed`

  • Discard unchanged with heartbeat: `1h`

| |Service [{#SERVICE.NAME}, {#SERVICE.JOB}]: jobs 'error'|

Gets the number of jobs in the state - `error`.

|Dependent item|service.jobs.status['{#SERVICE.NAME}','{#SERVICE.JOB}',error]

**Preprocessing**

  • JSON Path: `$.statusByJobs.error`

  • Discard unchanged with heartbeat: `1h`

| ### Trigger prototypes for SLA services discovery |Name|Description|Expression|Severity|Dependencies and additional info| |----|-----------|----------|--------|--------------------------------| |Service [{#SERVICE.NAME}, {#SERVICE.JOB}]: status [{ITEM.VALUE}]|

The service has encountered an issue.

|`last(/Control-M enterprise manager by HTTP/service.status['{#SERVICE.NAME}','{#SERVICE.JOB}'],#1)=0 or last(/Control-M enterprise manager by HTTP/service.status['{#SERVICE.NAME}','{#SERVICE.JOB}'],#1)=10`|Average|**Manual close**: Yes| |Service [{#SERVICE.NAME}, {#SERVICE.JOB}]: status [{ITEM.VALUE}]|

The service has finished its job late.

|`last(/Control-M enterprise manager by HTTP/service.status['{#SERVICE.NAME}','{#SERVICE.JOB}'],#1)=3`|Warning|**Manual close**: Yes| |Service [{#SERVICE.NAME}, {#SERVICE.JOB}]: jobs in 'error' state|

There are services present which are in the state - `error`.

|`last(/Control-M enterprise manager by HTTP/service.jobs.status['{#SERVICE.NAME}','{#SERVICE.JOB}',error],#1)>0`|Average|| ## Feedback Please report any issues with the template at [`https://support.zabbix.com`](https://support.zabbix.com) You can also provide feedback, discuss the template, or ask for help at [`ZABBIX forums`](https://www.zabbix.com/forum/zabbix-suggestions-and-feedback)