[Development Guides Home](/guides) >> [Guide to cPanel Plugins](/guides/guide-to-cpanel-plugins)

# Guide to cPanel Plugins - Pluggable Statistics Modules

## Introduction

Pluggable statistics modules can display custom statistics items in the cPanel interface.

## Module behavior

Before you create a custom statistics module, make certain that you understand how the system interacts with custom statistics modules:

* If any item in a module fails, this function will **not** display any items from that module. However, failure in one module will not prevent the display of other modules.
* Custom data modules execute on every cPanel [*Tools*](https://docs.cpanel.net/cpanel/the-cpanel-interface/the-cpanel-interface/#the-tools-page) interface page load.
  * The interface loads custom modules after the initial page load.
  * The system does not cache the data that custom modules poll.


The presence of the `/var/cpanel/perl/Cpanel/ResourceUsage/Custom` directory triggers each `ResourceUsage` call. Every time that a user loads or refreshes the cPanel *Tools* interface, the system **must** open and list the contents of that directory. If no modules exist in the directory, you should delete the directory to avoid the extra disk load.

## Create the custom module

To create a custom statistics module, create the `/var/cpanel/perl/Cpanel/ResourceUsage/Custom/modulename.pm` file, where `modulename` represents your new module's name.

Note:
* You **must** create a unique module name.
* The system can process multiple custom modules.


The custom module will resemble the following:


```
package Cpanel::ResourceUsage::Custom::modulename;

use strict;
use warnings;

# This feature expects each custom module to contain a "get_usages" function
# that returns an array of hashes, with each hash matching the parameters below:

sub get_usages {
    my ($username) = @_;

    return (
        {
            id          => 'custom_statistic1',     #string, not displayed
            description => 'new custom statistic 1',    #string, displayed
            usage       => 0,                       #nonnegative integer
            maximum     => 1,                       #optional, nonnegative integer
            formatter   => 'format_bytes',          #optional; if defined, the value is passed through the specified formatter for display
            app         => 'file_manager',          #optional, to link to a cPanel interface
            before      => 'forwarders',            #optional, to display immediately before another entry
        },
        {
            id          => 'custom_statistic2',       #string, not displayed
            description => 'new custom statistic 2',      #string, displayed
            usage       => 1,                         #nonnegative integer
            maximum     => undef,                     #optional, nonnegative integer
            formatter   => 'format_bytes_per_second', #optional; if defined, the value is passed through the specified formatter for display
            url         => 'https://www.example.com', #optional, to link to a URL
            after       => 'email_accounts',          #optional, to display immediately after another entry
        },
        # insert any other modules here …
    );
}

1;
```

### Parameters

Use the following parameters to configure the module:

| Key | Type | Description | Possible Values | Example |
|  --- | --- | --- | --- | --- |
| `id` | *string* | **Required**  The identifier.  **Note:** The system uses this value to determine the item display order.If you create two or more items with the same `id` value, the **last** item will display in the interface and this function will ignore the others.You **must** use a unique `id` value across all modules. The system has default [`ResourceUsage` IDs](#resourceusage-ids) which the user can override. | ASCII, spaces, and the underscore (`_`) character. | `new item id` |
| `description` | *string* | **Required**  The text to display to users in the interface. **Note:** This function converts all lowercase strings to start case (all words start with a capital letter). For example, a value of `new custom stat` will display as *New Custom Stat* in the interface. | ASCII, spaces , and the underscore ( `_` ) character. | `new item description` |
| `usage` | *integer* | **Required**  The amount of the resource that the item uses. **Note:**  Items whose `usage` values approach the `maximum` value display at the top of the statistics bar. | A positive integer.`0` | `1` |
| `maximum` | *integer* | The maximum value of the range for the item. The system defaults to unlimited and displays the infinity symbol (`∞`) in the interface  if any of the following conditions are true: You do not include this parameter.You do not supply a value.  You enter `undef`. | A positive integer.`0`  **Note:**  If you enter a string for the `maximum` parameter instead of an integer, the function will display *NaN*. | `100` |
| `formatter` | *string* | Applies units to the usage value based on the specified formatter. If you do not include this parameter, the system will not display any units to the user.`format_bytes` — This function will convert the `usage` value into a storage format (for example, *MB* or *GB*).`format_bytes_per_second` — This function will convert the `usage` value into a storage format per second (for example, `2048` displays *2 KB/s*).   **Important:**  Any unrecognized value will cause an error. | `format_bytes``format_bytes_per_second` | `format_bytes` |
| `app` | *string* | A link that will redirect the user to a specific cPanel interface. If you do not include this parameter, the item will **not** include a link.**Note:**  For each item, you can **only** use the `app` **or** the `url` parameter, not both. | A valid appkey in the specified format. This link will **only** appear when the statistic is at or above 80% usage. For a list of available appkeys, use WHM API 1's [`get_users_links`](https://api.docs.cpanel.net/openapi/whm/operation/get_users_links/) function. | `Backups_Home` |
| `url` | *string* | A link that will redirect the user to a valid domain. If you do **not** include this parameter, the item does **not** include a link.**Note:**  For each item, you can **only** use the `app` **or** the `url` parameter, not both. | A valid URL. This link will **only** appear when the statistic is at or above 80% usage.  **Warning:**  The URL **must** contain the `https://` or `http://` protocol. | `https://www.example.com` |
| `before` | *string* | Display this item before another item.  **Note:**  For each item, you can **only** use the `before` **or** the `after` parameter, not both. For more information, read the [Customize Sort Order](#customize-sort-order) section below. | A valid [`ResourceUsage` IDs](#resourceusage-ids) or custom item's `id`. | `disk_usage` |
| `after` | *string* | Display this item after another item.  **Note:**  For each item, you can **only** use the `before` **or** the `after` parameter, not both. For more information, read the [Customize Sort Order](#customize-sort-order) section below. | A valid [`ResourceUsage` IDs](#resourceusage-ids) or custom item's `id`. | `cachedmysqldiskusage` |


### ResourceUsage IDs

The system uses the following default `ResourceUsage` IDs listed in the order they appear in the interface:

* `disk_usage`
* `cachedmysqldiskusage` (MySQL® Disk Usage)
* `bandwidth`
* `addon_domains`
* `subdomains`
* `aliases`
* `email_accounts`
* `mailing_lists`
* `autoresponders`
* `forwarders`
* `email_filters`
* `ftp_accounts`
* `mysql_databases`


If you create a custom item that uses any of the above values for the `id` parameter, the custom item will replace the default item.

### Customize Sort Order

Note:
* Items whose `usage` value approaches the maximum value display at the top of the statistics bar.
* For each item, you can **only** use the `before` or the `after` parameter, not both.
* If you create a custom item that uses any of the following values for the `id` parameter, the custom item will replace the default item.


Enter a [`ResourceUsage` ID](#resourceusage-ids) or a custom `id` for either the `before` or `after` parameter to customize the sort order. The value of the `before` or `after` parameter **must** exactly match the [`ResourceUsage` IDs](#resourceusage-ids) or your custom item's `id` value. If this value doesn’t match another item’s `id`, this function sorts custom items to the bottom of the statistics bar.

**For example:**

The following entry will appear first on the *Statistics* panel.


```
{
    id          => 'custom_statistic1',     #string, not displayed
    description => 'custom statistic 1',    #string, displayed
    usage       => 0,                       #nonnegative integer
    maximum     => 1,                       #optional, nonnegative integer
    formatter   => 'format_bytes',          #optional; if defined, the value is passed through the specified formatter for display
    app         => 'file_manager',          #optional, to link to a cPanel interface
    before      => 'bandwidth',             #optional, to display immediately before another entry
}
```