クリアフィルター
記事
Mihoko Iijima · 2022年4月13日
開発者の皆さん、こんにちは!
この記事では、InterSystems Global コンテストで見事優勝🏆された @Yuri.Gomes さんの作品をご紹介します!(ご本人が投稿された記事を使ってご紹介します)
InterSystems IRIS の「Global」はデータベースに格納される変数で、キーバリュー形式でアクセスできます。キーが複数ある場合は、配列の添え字を利用して階層のようなイメージで格納することもできます。
ここでご紹介する優勝作品は、配列をうまく利用した作品で、MindMapで書いた情報そのまま(見たまま)をグローバルに登録しています。
MindMapの表示部分については、オープンソースの Mind-elixir を使用されているようです。
ソースコードは OpenExchange で公開中で、git clone 後、 docker-compose up -d --build したらすぐ動きます!(docker 🐳ほんとに便利ですね!)
また、ご本人の解説ビデオも YouTube で絶賛公開中です!お手元で動かさなくてもどんな感じで Global が使われているか、どんな感じで Web アプリを作成されているのかを確認できますので、ぜひご覧ください!
Global の登録内容は 2:26秒辺りから、フロントエンドの解説は 3:11 辺りから
以下、Yuri さんが投稿された記事の内容です。
Global は、データを永続化する InterSystems IRIS のコアとなるものです。柔軟性があり、JSON ドキュメント、リレーショナル・データ、オブジェクト指向データ、OLAP キューブ、および Mindmaps のようなカスタム・データ・モデルを保存できます。
グローバルを使用してMindMp データを保存、削除、取得する方法については、以下の手順をご参照ください。
docker/docker-compose/git がインストールされている環境でお試しください。
1. サンプルコードをローカルに clone/pull する手順は以下の通りです。
$ git clone https://github.com/yurimarx/global-mindmap.git
2. clone後、作成されたディレクトリに移動し、ターミナルで以下実行し、イメージをビルドします。
$ docker-compose build
3. 以下のコマンドを実行し、コンテナを開始します。
$ docker-compose up -d
4. Mindmap フロントエンドを開き、👆に貼っているGIFアニメのように動かす場合は http://localhost:3000 にアクセスします(または、http://localhost:52773/mindmap/index.html を開きます)。
ソースコードについての解説
保存するデータの構造は以下の通りです (詳細はこちらをご覧ください: https://www.npmjs.com/package/mind-elixir):
{
topic: 'node topic',
id: 'bd1c24420cd2c2f5',
style: { fontSize: '32', color: '#3298db', background: '#ecf0f1' },
parent: null,
tags: ['Tag'],
icons: ['😀'],
hyperLink: 'https://github.com/ssshooter/mind-elixir-core',
}
parent プロパティは、MindMap のノード間に親子関係を構築するために使用されます。
^mindmap グローバルに登録する部分のソースコード
ClassMethod StoreMindmapNode
/// Store mindmap node
ClassMethod StoreMindmapNode() As %Status
{
Try {
Set data = {}.%FromJSON(%request.Content)
Set ^mindmap(data.id) = data.id /// set mindmap key
Set ^mindmap(data.id, "topic") = data.topic /// set topic subscript
Set ^mindmap(data.id, "style", "fontSize") = data.style.fontSize /// set style properties subscripts
Set ^mindmap(data.id, "style", "color") = data.style.color
Set ^mindmap(data.id, "style", "background") = data.style.background
Set ^mindmap(data.id, "parent") = data.parent /// store parent id subscript
Set ^mindmap(data.id, "tags") = data.tags.%ToJSON() /// store tags subscript
Set ^mindmap(data.id, "icons") = data.icons.%ToJSON() /// store icons subscript
Set ^mindmap(data.id, "hyperLink") = data.hyperLink /// store hyperLink subscript
Set %response.Status = 200
Set %response.Headers("Access-Control-Allow-Origin")="*"
Write "Saved"
Return $$$OK
} Catch err {
write !, "Error name: ", ?20, err.Name,
!, "Error code: ", ?20, err.Code,
!, "Error location: ", ?20, err.Location,
!, "Additional data: ", ?20, err.Data, !
Return $$$NOTOK
}
}
^mindmap グローバルを作成しています。mindmap のプロパティについては、Global の添え字に設定しています。添え字のキーは mindmap の id プロパティの値を設定しています。
^mindmap ノードを削除するサンプルコード: Global の kill (削除)
ClassMethod DeleteMindmapNode
/// Delete mindmap node
ClassMethod DeleteMindmapNode(id As %String) As %Status
{
Try {
Kill ^mindmap(id) /// delete selected mindmap node using the id (global key)
Set %response.Status = 200
Set %response.Headers("Access-Control-Allow-Origin")="*"
Write "Deleted"
Return $$$OK
} Catch err {
write !, "Error name: ", ?20, err.Name,
!, "Error code: ", ?20, err.Code,
!, "Error location: ", ?20, err.Location,
!, "Additional data: ", ?20, err.Data, !
Return $$$NOTOK
}
}
このサンプルでは、minamap.id を ^mindmap グローバルのキーとして利用しているので削除は簡単です。以下実行するだけです。
kill ^mindmap(<mindmap id>)
全格納情報を取得するコード例 - $ORDER()関数を使用してGlobal をループする
ClassMethod GetMindmap - return all mindmap global nodes
/// Get mindmap content
ClassMethod GetMindmap() As %Status
{
Try {
Set Nodes = []
Set Key = $Order(^mindmap("")) /// get the first mindmap node stored - the root
Set Row = 0
While (Key '= "") { /// while get child mindmap nodes
Do Nodes.%Push({}) /// create a item into result
Set Nodes.%Get(Row).style = {}
Set Nodes.%Get(Row).id = Key /// return the id property
Set Nodes.%Get(Row).hyperLink = ^mindmap(Key,"hyperLink") /// return the hyperlink property
Set Nodes.%Get(Row).icons = ^mindmap(Key,"icons") /// return icons property
Set Nodes.%Get(Row).parent = ^mindmap(Key,"parent") /// return parent id property
Set Nodes.%Get(Row).style.background = ^mindmap(Key,"style", "background") /// return the style properties
Set Nodes.%Get(Row).style.color = ^mindmap(Key,"style", "color")
Set Nodes.%Get(Row).style.fontSize = ^mindmap(Key,"style", "fontSize")
Set Nodes.%Get(Row).tags = ^mindmap(Key,"tags") /// return tags property
Set Nodes.%Get(Row).topic = ^mindmap(Key,"topic") /// return topic property (title mindmap node)
Set Row = Row + 1
Set Key = $Order(^mindmap(Key)) /// get the key to the next mindmap global node
}
Set %response.Status = 200
Set %response.Headers("Access-Control-Allow-Origin")="*"
Write Nodes.%ToJSON()
Return $$$OK
} Catch err {
write !, "Error name: ", ?20, err.Name,
!, "Error code: ", ?20, err.Code,
!, "Error location: ", ?20, err.Location,
!, "Additional data: ", ?20, err.Data, !
Return $$$NOTOK
}
}
^mindmap グローバルの第1番目の添え字にある最初の情報(ルートノード)を取得するために、$Order(^mindmap("")) を実行しています(取得した内容は変数 Key に設定しています)。
^mindmap(Key, <property name>) を使用して、各プロパティ値を取得しています。次に登録されている Key を取得するため、While文の最後に $Order(^mindmap(Key) を実行しています。
フロントエンド
MindMap のレンダリングと編集には Mind-elixir と React が使われ、IRIS で構築された API バックエンドを呼び出しています。詳細は、MindMap の react コンポーネントを参照してください。
Mindmap React component - consuming IRIS REST API
import React from "react";
import MindElixir, { E } from "mind-elixir";
import axios from 'axios';
class Mindmap extends React.Component {
componentDidMount() {
this.dynamicWidth = window.innerWidth;
this.dynamicHeight = window.innerHeight;
axios.get(`http://localhost:52773/global-mindmap/hasContent`)
.then(res => {
if (res.data == "1") {
axios.get(`http://localhost:52773/global-mindmap/get`)
.then(res2 => {
this.ME = new MindElixir({
el: "#map",
direction: MindElixir.LEFT,
data: this.renderExistentMindmap(res2.data),
draggable: true, // default true
contextMenu: true, // default true
toolBar: true, // default true
nodeMenu: true, // default true
keypress: true // default true
});
this.ME.bus.addListener('operation', operation => {
console.log(operation)
if (operation.name == 'finishEdit' || operation.name == 'editStyle') {
this.saveMindmapNode(operation.obj)
} else if (operation.name == 'removeNode') {
this.deleteMindmapNode(operation.obj.id)
}
})
this.ME.init();
})
} else {
this.ME = new MindElixir({
el: "#map",
direction: MindElixir.LEFT,
data: MindElixir.new("New Mindmap"),
draggable: true, // default true
contextMenu: true, // default true
toolBar: true, // default true
nodeMenu: true, // default true
keypress: true // default true
});
this.ME.bus.addListener('operation', operation => {
console.log(operation)
if (operation.name == 'finishEdit' || operation.name == 'editStyle') {
this.saveMindmapNode(operation.obj)
} else if (operation.name == 'removeNode') {
this.deleteMindmapNode(operation.obj.id)
}
})
this.saveMindmapNode(this.ME.nodeData)
this.ME.init();
}
})
}
render() {
return (
<div id="map" style={{ height: window.innerHeight + 'px', width: '100%' }} />
);
}
deleteMindmapNode(mindmapNodeId) {
axios.delete(`http://localhost:52773/global-mindmap/delete/${mindmapNodeId}`)
.then(res => {
console.log(res);
console.log(res.data);
})
}
saveMindmapNode(node) {
axios.post(`http://localhost:52773/global-mindmap/save`, {
topic: (node.topic == undefined ? "" : node.topic),
id: node.id,
style: (node.style == undefined ? "" : node.style),
parent: (node.parent == undefined ? "" : node.parent.id),
tags: (node.tags == undefined ? [] : node.tags),
icons: (node.icons == undefined ? [] : node.icons),
hyperLink: (node.hyperLink == undefined ? "" : node.hyperLink)
})
.then(res => {
console.log(res);
console.log(res.data);
})
}
renderExistentMindmap(data) {
let root = data[0]
let nodeData = {
id: root.id,
topic: root.topic,
root: true,
style: {
background: root.style.background,
color: root.style.color,
fontSize: root.style.fontSize,
},
hyperLink: root.hyperLink,
children: []
}
this.createTree(nodeData, data)
return { nodeData }
}
createTree(nodeData, data) {
for(let i = 1; i < data.length; i++) {
if(data[i].parent == nodeData.id) {
let newNode = {
id: data[i].id,
topic: data[i].topic,
root: false,
style: {
background: data[i].style.background,
color: data[i].style.color,
fontSize: data[i].style.fontSize,
},
hyperLink: data[i].hyperLink,
children: []
}
nodeData.children.push(newNode)
this.createTree(newNode, data)
}
}
}
}
export default Mindmap;
もし、このサンプルコードが気に入りましたら、InterSystems Global コンテストで私の作品に投票してください!
ありがとうございました。
記事
Tomohiro Iwamoto · 2020年6月5日
前回の記事では、pButtonsを使って履歴パフォーマンスメトリックを収集する方法を説明しました。 すべてのデータプラットフォームインスタンス(Ensemble、Cachéなど)にはpButtonsがインストールされていることがわかっているため、私はpButtonsを使用する傾向にありますが、 Cachéパフォーマンスメトリックをリアルタイムで収集、処理、表示する方法はほかにもあり、単純な監視や、それよりもさらに重要な、より高度な運用分析とキャパシティプランニングに使用することができます。 データ収集の最も一般的な方法の1つは、SNMP(簡易ネットワーク管理プロトコル)を使用することです。
SNMPは、Cachéが管理・監視情報をさまざまな管理ツールに提供するための標準的な方法です。 Cachéのオンラインドキュメンテーションには、CachéとSNMP間のインターフェースに関する詳細が説明されています。 SNMPはCachéと「単純に連携」するはずですが、構成にはいくつかの技と罠があります。 私自身、はじめに何度も過ちを繰り返し、InterSystemsの同僚から助けを得ながらCachéをオペレーティングシステムのSNMPマスターエージェントにやっと接続できた経験から、皆さんが同じような困難を避けられるようにこの記事を書くことにしました。
この記事では、Red Hat Linuxで実行するCachéにおけるSNMPのセットアップと構成について説明します。ほかの *nixフレーバーでも同じ手順を使用できるはずです。 Linuxの場合はセットアップにもう少しコツが必要なので、Red Hatを使ってこの記事を書いています。WindowsのCachéは、自動的にDLLをインストールして標準のWindows SNMPサービスに接続するため、より簡単に構成できます。
サーバー側でSNMPのセットアップが完了したら、複数のツールを使用して監視を開始できます。 私は一般的なPRTGツールを使って監視を説明しようと思いますが、ほかにもたくさんのツールがあります。ここに示すのはリストの一部です。
CachéとEnsembleのMIBファイルは Cachéインストールディレクトリ/SNMP フォルダにあります。ファイルは ISC-CACHE.mib と ISC-ENSEMBLE.mib です。
このシリーズのこれまでの記事:
パート1 - はじめの一歩。メトリックの収集。
パート2 - 収集したメトリックの確認。
パート3 - CPUに注目
パート4 - メモリの確認。
まずはここから始めましょう...
まず、Cachéオンラインドキュメンテーションの「Monitoring Caché Using SNMP(SNMPによるCachéの監視)」を確認してください。
1. Cachéを構成する
Caché オンラインドキュメンテーションの「Managing SNMP in Caché(CachéでのSNMPの管理)」セクションにある手順に従って、Caché監視サービスを有効化し、Caché SNMPサブエージェントがCachéの起動時に自動的に開始するように構成します。
OSのプロセスリストを確認するなどして、Cachéプロセスが実行していることを確認します。
ps -ef | grep SNMP
root 1171 1097 0 02:26 pts/1 00:00:00 grep SNMP
root 27833 1 0 00:34 pts/0 00:00:05 cache -s/db/trak/hs2015/mgr -cj -p33 JOB^SNMP
これで、Cachéの構成は完了です!
2. オペレーティングシステムを構成する
ここでは、もう少しやることがあります。 まず、snmpdデーモンがインストール済みで実行中であることを確認してください。 そうでない場合はsnmpdをインストールして開始します。
次ようにして、snmpdのステータスを確認します。
service snmpd status
次のようにして、snmpdを開始または停止します。
service snmpd start|stop
snmpがインストールされていない場合は、OSの指示に従ってインストールする必要があります。次に例を示します。
yum -y install net-snmp net-snmp-utils
3. snmpdを構成する
Cachéドキュメンテーションで説明されるとおり、Linuxシステムで最も重要なタスクは、システム上のSNMPマスターエージェントがAgent Extensibility(AgentX)プロトコルと互換性があり(Cachéはサブエージェントとして実行)、マスターがアクティブで標準のAgentX TCPポート705で待ち受け状態であることを確認することです。
私が壁にぶつかったのは、この部分でした。 snmp.confファイルで基本的なミスをしてしまったせいで、Caché SNMPサブエージェントがOSマスターエージェントと通信していませんでした。 次の /etc/snmp/snmp.conf サンプルファイルはagentXを開始してCachéとEnsembleのSNMP MIBにアクセスを提供するように構成されています。
次の構成があなたの組織のセキュリティポリシーを順守しているかどうかを確認する必要があります。
システムの設定が反映されるように、少なくとも次の行を編集する必要があります。
例えば、
syslocation "System_Location"
の行を次のように変更します。
syslocation "Primary Server Room"
また、少なくとも次の2行を編集します。
syscontact "Your Name"
trapsink Caché_database_server_name_or_ip_address public
次と一致するように、既存の/etc/snmp/snmp.conf ファイルを編集するか置換します。
###############################################################################
#
# snmpd.conf:
# An example configuration file for configuring the NET-SNMP agent with Cache.
#
# This has been used successfully on Red Hat Enterprise Linux and running
# the snmpd daemon in the foreground with the following command:
#
# /usr/sbin/snmpd -f -L -x TCP:localhost:705 -c./snmpd.conf
#
# You may want/need to change some of the information, especially the
# IP address of the trap receiver of you expect to get traps. I've also seen
# one case (on AIX) where we had to use the "-C" option on the snmpd command
# line, to make sure we were getting the correct snmpd.conf file.
#
###############################################################################
###########################################################################
# SECTION: System Information Setup
#
# This section defines some of the information reported in
# the "system" mib group in the mibII tree.
# syslocation: The [typically physical] location of the system.
# Note that setting this value here means that when trying to
# perform an snmp SET operation to the sysLocation.0 variable will make
# the agent return the "notWritable" error code. IE, including
# this token in the snmpd.conf file will disable write access to
# the variable.
# arguments: location_string
syslocation "System Location"
# syscontact: The contact information for the administrator
# Note that setting this value here means that when trying to
# perform an snmp SET operation to the sysContact.0 variable will make
# the agent return the "notWritable" error code. IE, including
# this token in the snmpd.conf file will disable write access to
# the variable.
# arguments: contact_string
syscontact "Your Name"
# sysservices: The proper value for the sysServices object.
# arguments: sysservices_number
sysservices 76
###########################################################################
# SECTION: Agent Operating Mode
#
# This section defines how the agent will operate when it
# is running.
# master: Should the agent operate as a master agent or not.
# Currently, the only supported master agent type for this token
# is "agentx".
#
# arguments: (on|yes|agentx|all|off|no)
master agentx
agentXSocket tcp:localhost:705
###########################################################################
# SECTION: Trap Destinations
#
# Here we define who the agent will send traps to.
# trapsink: A SNMPv1 trap receiver
# arguments: host [community] [portnum]
trapsink Caché_database_server_name_or_ip_address public
###############################################################################
# Access Control
###############################################################################
# As shipped, the snmpd demon will only respond to queries on the
# system mib group until this file is replaced or modified for
# security purposes. Examples are shown below about how to increase the
# level of access.
#
# By far, the most common question I get about the agent is "why won't
# it work?", when really it should be "how do I configure the agent to
# allow me to access it?"
#
# By default, the agent responds to the "public" community for read
# only access, if run out of the box without any configuration file in
# place. The following examples show you other ways of configuring
# the agent so that you can change the community names, and give
# yourself write access to the mib tree as well.
#
# For more information, read the FAQ as well as the snmpd.conf(5)
# manual page.
#
####
# First, map the community name "public" into a "security name"
# sec.name source community
com2sec notConfigUser default public
####
# Second, map the security name into a group name:
# groupName securityModel securityName
group notConfigGroup v1 notConfigUser
group notConfigGroup v2c notConfigUser
####
# Third, create a view for us to let the group have rights to:
# Make at least snmpwalk -v 1 localhost -c public system fast again.
# name incl/excl subtree mask(optional)
# access to 'internet' subtree
view systemview included .1.3.6.1
# access to Cache MIBs Caché and Ensemble
view systemview included .1.3.6.1.4.1.16563.1
view systemview included .1.3.6.1.4.1.16563.2
####
# Finally, grant the group read-only access to the systemview view.
# group context sec.model sec.level prefix read write notif
access notConfigGroup "" any noauth exact systemview none none
/etc/snmp/snmp.confファイルの編集が完了したら、snmpdデーモンを再起動します。
service snmpd restart
snmpdのステータスを確認します。AgentXが開始されていることに注意してください。ステータス行に「Turning on AgentX master support」が表示されます。
h-4.2# service snmpd restart
Redirecting to /bin/systemctl restart snmpd.service
sh-4.2# service snmpd status
Redirecting to /bin/systemctl status snmpd.service
● snmpd.service - Simple Network Management Protocol (SNMP) Daemon.
Loaded: loaded (/usr/lib/systemd/system/snmpd.service; disabled; vendor preset: disabled)
Active: active (running) since Wed 2016-04-27 00:31:36 EDT; 7s ago
Main PID: 27820 (snmpd)
CGroup: /system.slice/snmpd.service
└─27820 /usr/sbin/snmpd -LS0-6d -f
Apr 27 00:31:36 vsan-tc-db2.iscinternal.com systemd[1]: Starting Simple Network Management Protocol (SNMP) Daemon....
Apr 27 00:31:36 vsan-tc-db2.iscinternal.com snmpd[27820]: Turning on AgentX master support.
Apr 27 00:31:36 vsan-tc-db2.iscinternal.com snmpd[27820]: NET-SNMP version 5.7.2
Apr 27 00:31:36 vsan-tc-db2.iscinternal.com systemd[1]: Started Simple Network Management Protocol (SNMP) Daemon..
sh-4.2#
snmpdを再起動したら、^SNMPルーチンを使用してCaché SNMPサブエージェントを再起動する必要があります。
%SYS>do stop^SNMP()
%SYS>do start^SNMP(705,20)
オペレーティングシステムのsnmpdデーモンとCachéサブエージェントが実行しており、アクセスできるようになっているはずです。
4. MIBアクセスを検証する
MIBアクセスは、コマンドラインで以下のコマンドを使って確認できます。snmpgetは、単一の値を返します。
snmpget -mAll -v 2c -c public vsan-tc-db2 .1.3.6.1.4.1.16563.1.1.1.1.5.5.72.50.48.49.53
SNMPv2-SMI::enterprises.16563.1.1.1.1.5.5.72.50.48.49.53 = STRING: "Cache for UNIX (Red Hat Enterprise Linux for x86-64) 2015.2.1 (Build 705U) Mon Aug 31 2015 16:53:38 EDT"
そして、snmpwalkは、MIBツリーまたはブランチを「ウォーク」します。
snmpwalk -m ALL -v 2c -c public vsan-tc-db2 .1.3.6.1.4.1.16563.1.1.1.1
SNMPv2-SMI::enterprises.16563.1.1.1.1.2.5.72.50.48.49.53 = STRING: "H2015"
SNMPv2-SMI::enterprises.16563.1.1.1.1.3.5.72.50.48.49.53 = STRING: "/db/trak/hs2015/cache.cpf"
SNMPv2-SMI::enterprises.16563.1.1.1.1.4.5.72.50.48.49.53 = STRING: "/db/trak/hs2015/mgr/"
etc
etc
また、システムデータの表示には、さまざまなウィンドウと *nixクライアントを使用できます。 私は無料のiReasoning MIB Browserを使用しています。 MIBの構造を認識させるために、ISC-CACHE.MIBファイルをクライアントにロードする必要があります。
次の画像は、OS X上のiReasoning MIB Browserをキャプチャしたものです。
監視ツールに含める
これが、実装に大きな違いを生じる可能性のあるところです。 監視ツールや分析ツールの選択は、あなたにお任せすることにします。
システムの監視と管理に使用するツールとそれから得られる価値について、コメント欄で詳しくお聞かせください。 他のコミュニティメンバーにとっても非常に役立つと思います。
次は、一般的に使用されているPRTG Network Monitorのスクリーンショットで、Cachéメトリックが表示されています。 CachéメトリックをPRTGに含める手順はほかのツールと同じです。
ワークフローの例 - 監視ツールをCaché MIBに追加する。
ステップ 1.
オペレーティングシステムのMIBに接続できることを確認します。 ヒントは、Cachéではなく、オペレーティングシステムに対してトラブルシューティングを行うということです。 監視ツールは一般的なオペレーティングシステムのMIBをすでに認識しており、あらかじめ構成されている可能性が高いため、ベンダーやほかのユーザーから支援を得る方が簡単かもしれません。
選択した監視ツールによっては、SNMP「モジュール」または「アプリケーション」を追加する必要がある場合があります。これらは通常無料で、オープンソースです。 この手順では、ベンダーが作成した指示が非常にわかりやすいと思いました。
オペレーティングシステムのメトリックを監視できるようになったら、Cachéを追加します。
ステップ 2.
ISC-CACHE.mib と ISC-ENSEMBLE.mib をツールにインポートして、MIB構造を認識できるようにします。
ここでの手順はツールによって異なります。PRTGの場合は「MIB Importer」ユーティリティが提供されています。 基本的には、ツールで ISC-CACHE.mib テキストファイルを開いて、ツールの内部形式にインポートする、という手順です。 たとえば、SplunkではPython形式が使用されています。
注意: すべてのCaché MIBブランチでセンサーを追加しようとすると、PRTGツールはタイムアウトしてしまいました。 ツリー全体をウォークし、プロセスリストなどのいくつかのメトリックでタイムアウトしたのだと思います。このトラブルシューティングに時間をかける代わりに、 ISC-CACHE.mibからパフォーマンスブランチ(cachePerfTab)のみをインポートすることで問題を回避しました。
インポートと変換が完了したら、ネットワークのほかのサービスからデータを収集するためにMIBを再利用することができます。 上の図では、PRTGがSensor Factoryセンサを使用して複数のセンサを1つのチャートに結合しています。
最後に
監視ツール、警告ツール、そして非常に高度なスマート分析ツールにはさまざまなものがあり、無料で提供されているものもあれば、サポートライセンス付きのものもあり、機能も多岐に渡ります。
システムを監視し、どのアクティビティが正常であり正常外であるのかを理解し、調査する必要があります。 SNMPは、CachéとEnsembleのメトリックを確認できるようにするための簡単な方法と言えます。