Monitoring Toolkit
Monitor is an open-source framework that makes it easy to extract and transform on-chain data into targeted, timely smart messages. You can implement a monitor service to provide your dApp's users with smart messages.
The monitor framework provides features to seamlessly integrate notifications with your dApp:
- Ability to track dApp users that subscribe to notifications
- Ability to continuously monitor on-chain resources, like accounts, for a set of your subscribers
- A rich, high-level API for unbounded data-stream processing to analyze the extracted on-chain data
Data-stream processing features include:
- Windowing: fixed size, fixed time, fixed size sliding
- Aggregation: average, min, max
- Thresholding: rising edge, falling edge
- Rate limiting
Installation
npm:
npm install @dialectlabs/monitor
yarn:
yarn add @dialectlabs/monitor
Usage
Dialect's monitor is best learned by example. This section describes how to use Dialect monitor to build a monitoring apps by showing you various example apps in the examples/
folder of this repository. Follow along in this section, & refer to the code in those examples.
Examples start from real application that is utilizing solana blockchain and dialect program, then we provide some examples
that don't utilize solana as a dependency to run for development simplicity.
examples/000.1-solana-monitoring-service.ts
This example emulates e2e scenario for monitoring some on chain resources for a set of subscribers and has 2 parts:
- Client that emulates several users subscribing for dialect notifications from a monitoring service
- Server that monitors some data for a set of monitoring service subscribers
Server example:
import { Monitor, Monitors, Pipelines, ResourceId, SourceData } from '../src';
import { Duration } from 'luxon';
import {
Dialect,
DialectCloudEnvironment,
DialectSdk,
} from '@dialectlabs/sdk';
import {
Solana,
SolanaSdkFactory,
NodeDialectSolanaWalletAdapter
} from '@dialectlabs/blockchain-sdk-solana';
const environment: DialectCloudEnvironment = 'development';
const dialectSolanaSdk: DialectSdk<Solana> = Dialect.sdk(
{
environment,
},
SolanaSdkFactory.create({
wallet: NodeDialectSolanaWalletAdapter.create(),
}),
);
type YourDataType = {
cratio: number;
healthRatio: number;
resourceId: ResourceId;
};
const dataSourceMonitor: Monitor<YourDataType> = Monitors.builder({
sdk: dialectSolanaSdk,
subscribersCacheTTL: Duration.fromObject({ seconds: 5 }),
})
.defineDataSource<YourDataType>()
.poll((subscribers: ResourceId[]) => {
const sourceData: SourceData<YourDataType>[] = subscribers.map(
(resourceId) => ({
data: {
cratio: Math.random(),
healthRatio: Math.random(),
resourceId,
},
groupingKey: resourceId.toString(),
}),
);
return Promise.resolve(sourceData);
}, Duration.fromObject({ seconds: 3 }))
.transform<number, number>({
keys: ['cratio'],
pipelines: [
Pipelines.threshold({
type: 'falling-edge',
threshold: 0.5,
}),
],
})
.notify()
.dialectSdk(
({ value }) => {
return {
title: 'dApp cratio warning',
message: `Your cratio = ${value} below warning threshold`,
};
},
{
dispatch: 'unicast',
to: ({ origin: { resourceId } }) => resourceId,
},
)
.also()
.transform<number, number>({
keys: ['cratio'],
pipelines: [
Pipelines.threshold({
type: 'rising-edge',
threshold: 0.5,
}),
],
})
.notify()
.dialectSdk(
({ value }) => {
return {
title: 'dApp cratio warning',
message: `Your cratio = ${value} above warning threshold`,
};
},
{
dispatch: 'unicast',
to: ({ origin: { resourceId } }) => resourceId,
},
)
.and()
.build();
dataSourceMonitor.start();
Please follow the instructions below to run the example
Step 1. Generate a new test keypair representing your dapp's monitoring service
export your_path=~/projects/dialect/keypairs/
solana-keygen new --outfile ${your_path}/monitor-localnet-keypair.private
solana-keygen pubkey ${your_path}/monitor-localnet-keypair.private > ${your_path}/monitor-localnet-keypair.public
Step 2. Start server with keypair assigned to env DIALECT_SDK_CREDENTIALS
cd examples
export your_path=~/projects/dialect/keypairs
DIALECT_SDK_CREDENTIALS=$(cat ${your_path}/monitor-localnet-keypair.private) ts-node ./000.1-solana-monitoring-service-server.ts
Step 3. Start client
cd examples
export your_path=~/projects/dialect/keypairs
DAPP_PUBLIC_KEY=$(cat ${your_path}/monitor-localnet-keypair.public) \
ts-node ./000.1-solana-monitoring-service-client.ts
Step 4. Look at client logs for notifications
When both client and server are started, server will start polling data and notifying subscribers
001-data-source-monitor
Shows an example of how to define custom data source, transform data and generate notifications Doesn't exchange data
with on-chain program for development simplicity.
Start this example
cd examples
ts-node ./001-data-source-monitor.ts
002-subscribers-monitor
Shows an example of how subscribe to events about subscriber state changes and generate notifications. Useful e.g. for
sending new subscriber greetings or cleaning some data when subscriber removed. Doesn't exchange data with on-chain
program for development simplicity.
Start this example
cd examples
ts-node ./002-subscribers-monitor.ts
003-custom-subscriber-repository
Shows an example of how to define custom dummy subscriber repository instead of getting this data from DialectCloud. Useful for local development.
004-custom-notification-sink
Shows an example of how to write a custom notification sink. Console log example useful for local development.
005-custom-pipelines-using-operators
Shows an example of how to develop an analytical pipeline using a set of subsequent more low-level transformation
operators.
If you're interested in developing on Dialect while making live changes to the library, see the Development section below.
Development
Prerequisites
- Git
- Yarn (<2)
- Nodejs (>=15.10 <17)
Getting started with monitor development in this repo
Install dependencies
npm:
npm install
yarn:
yarn
Take a look at examples and corresponding readme file
After getting familiar with https://github.com/dialectlabs/monitor/blob/main/examples/README.md and examples you'll be ready to implement a new monitoring service.