LogicMonitor + Catchpoint: 自律型ITの新時代へ

さらに詳しく

LogicMonitor向けのArista VeloCloud SD-WANモニタリングスイートは、VeloCloud Orchestrator APIとSNMPの両方を活用し、エッジの健全性、リンクパフォーマンス、パスの信頼性を詳細に監視します。このモニタリングスイートにより、IT運用チームはネットワークの問題をプロアクティブに検出・解決し、SD-WANのパフォーマンスを最適化し、分散拠点間で一貫した可用性を維持できます。 

重要: Arista VeloCloud SD-WAN監視パッケージは、 VMware_SDWAN_ モジュール。データの重複や競合を防ぐため、展開前に以前の VMware モジュールがすべて削除されていることを確認してください。

Arista VeloCloud SD-WAN モニタリングの要件

Arista VeloCloud SD-WAN モニタリング スイートを展開および操作するには、次の点を確認してください。

  • VeloCloud Orchestratorポータルへのアクセス( vcoX.velocloud.net)
  • VeloCloud Orchestrator の API トークン (読み取り専用スコープを推奨)
  • リンクおよびパス メトリック用に各エッジで SNMP が有効になっています (UDP 161 到達可能)
  • コレクターから次のネットワーク アクセス:
    • HTTPS経由のVeloCloud Orchestrator(ポート443)
    • SNMP(UDP 161)

NetScan 重複排除の場合は、次の点を確認してください。

  • LogicMonitor APIアクセスID/キー(lmaccess.id / lmaccess.key or logicmonitor.access.id / logicmonitor.access.key)

監視へのリソースの追加

VeloCloud SD-WAN リソースは、次の方法で監視に追加できます。

適切な監視とデータ収集を可能にするために、VeloCloud SD-WANリソースに必要なプロパティと認証情報が設定されていることを確認してください。詳細については、以下を参照してください。 リソースへのプロパティの割り当て.

  1. LogicMonitorで、>に移動します。 モジュール > 交換 > 選択する ベロクラウド SD-WAN LogicModules をインストールします。 
  2. に移動します リソースツリー > リソースを追加高度なネットスキャン.
  3. 次の手順に従って、「Advanced NetScan の追加」フォームを完了します。
    1.   フィールドに、このNetScanに関連付ける名前を入力します。例:「VeloCloud SD-WAN」
    2. (オプション) 説明を追加するには、  詳細説明  フィールド。 
    3.  ネットスキャングループ フィールドに、NetScan グループを追加します。 
    4. (オプション)コレクターグループを選択するには、 コレクターグループ ドロップダウンメニュー。 
    5. ノーザンダイバー社の コレクタ ドロップダウン メニューで、NetScan を実行するコレクターを選択します。
      詳細については、を参照してください。 コレクターの割り当て

      注意: デフォルトでは、NetScan は NetScan を実行しているコレクターに新しいリソースを割り当てます。

    6. 「拡張スクリプトNetScan」を選択します。 発見方法 ドロップダウンメニュー。 
    7. (オプション)完了時にメール通知を送信するには、 スキャンが終了したら電子メール通知を送信します スイッチ。 
      メールを 受信者のメール フィールド。  
    8. 選択する このスキャンにカスタム資格情報を使用する に選出しました。 リソース資格情報 のセクションから無料でダウンロードできます。
    9. NetScan に必要な VeloCloud API 資格情報を提供し、NetScan がリソースを作成および整理する方法と場所を制御する次のプロパティを追加します。
      プロパティ必須
      velocloud.sdwan.orchestrator.hostVeloCloud Orchestratorのホスト名(例: vco1.velocloud.net).あり
      velocloud.sdwan.keyVeloCloud Orchestrator API トークン。あり
      velocloud.sdwan.enterprise.idOrchestrator 内のエンタープライズ ID。あり
      velocloud.sdwan.folder.nameNetScanが作成または使用するリソースグループの名前(ネストされた folder/folder/folder)。詳細については、 リソース グループの概要いいえ
      velocloud.sdwan.collector新しく追加されたリソースのコレクター ID。いいえ
      skip.device.dedupe重複デバイスのチェックをスキップします (非推奨)。いいえ
      lmaccess.id or logicmonitor.access.idリソースの重複を防ぐため、LogicMonitor APIアクセスIDを使用します。詳細については、 LogicMonitorポータルモニタリング.はい*
      lmaccess.key or logicmonitor.access.keyリソースの重複を防ぐためのLogicMonitor APIアクセスキー。詳細については、 LogicMonitorポータルモニタリング.はい*
      hostname.sourceNetScan が使用するホスト名ソースを選択します。NetScan のトラブルシューティングを参照してください。いいえ

      * skip.device.dedupe が設定されていない場合にのみ必要です。

      追加の包含フィルターまたは除外フィルターを設定できます(アクティブ検出フィルターと同様に動作します)。以下のデバイスレベルのプロパティは自動的に検出され、フィルターで使用できます(例えば、「等しくない」という条件で除外する場合など)。
      プロパティ
      velocloud.sdwan.edge.logical.idVeloCloud Edge 論理 ID
      velocloud.sdwan.edge.nameVeloCloud エッジ名
      velocloud.sdwan.serial.numberVeloCloud Edge シリアル番号
    10. 選択する Groovyスクリプトを埋め込む 次の VeloCloud SD-WAN Enhanced NetScan スクリプトを埋め込みます。
/*******************************************************************************
 *  © 2007-2025 - LogicMonitor, Inc. All rights reserved.
 ******************************************************************************/

import com.santaba.agent.groovy.utils.GroovyScriptHelper as GSH
import com.logicmonitor.mod.Snippets
import groovy.json.JsonOutput

def debug = false
def log = false

// Set props object based on whether or not we are running inside a netscan or debug console
def props
try {
    hostProps.get("system.hostname")
    props = hostProps
    debug = true  // set debug to true so that we can ensure we do not print sensitive properties
}
catch (MissingPropertyException) {
    props = netscanProps
}

// Import any needed credentials or properties that have been set in the UI
// Required properties
def key = props.get("velocloud.sdwan.key") ?: props.get("vmware.sdwan.key")
def enterpriseId = props.get("velocloud.sdwan.enterprise.id", props.get("vmware.sdwan.enterprise.id"))
def orchestratorHost = props.get("velocloud.sdwan.orchestrator.host", props.get("vmware.sdwan.orchestrator.host"))
def logCacheContext = "VeloCloud-SDWAN-${enterpriseId}-${orchestratorHost}"

// Bail out early if we don't have the necessary credentials
if (!key) {
    throw new Exception("Must provide credentials to run this script.  Verify necessary credentials have been provided in NetScan properties.")
}

// Bail out early if we don't have the necessary properties
if (!orchestratorHost) {
    throw new Exception("Must provide velocloud.sdwan.orchestrator.host and velocloud.sdwan.enterprise.id to run this script.  Verify necessary properties have been provided in NetScan properties.")
}

def modLoader = GSH.getInstance(GroovySystem.version).getScript("Snippets", Snippets.getLoader()).withBinding(getBinding())
def debugSnippet = modLoader.load("lm.debug", "1").debugSnippetFactory(out, debug, log, logCacheContext)
def emitSnippet = modLoader.load("lm.emit", "1")
def httpSnippet = modLoader.load("proto.http", "0").httpSnippetFactory(props)
def cacheSnippet = modLoader.load("lm.cache", "0").cacheSnippetFactory(debugSnippet, logCacheContext)
def veloCloudSnippet = modLoader.load("velocloud.sdwan", "1").veloCloudSdwanSnippetFactory(props, debugSnippet, httpSnippet, cacheSnippet)

// Optional properties
def rootFolder = props.get("velocloud.sdwan.folder.name") ?: "VeloCloud SD-WAN"
def collectorId = props.get("velocloud.sdwan.collector")

Boolean skipDeviceDedupe = props.get("skip.device.dedupe", "false").toBoolean()
String hostnameSource = props.get("hostname.source", "")?.toLowerCase()?.trim()

// Only initialize lmApi snippet class if customer has not opted out
def lmApi
if (!skipDeviceDedupe) {
    def lmApiSnippet = modLoader.load("lm.api", "0")
    lmApi = lmApiSnippet.lmApiSnippetFactory(props, httpSnippet, debugSnippet)
}

Map sensitiveProps = [
        "velocloud.sdwan.key": key,
]

// Get information about devices that already exist in LM portal
List fields = ["name", "currentCollectorId", "displayName", "systemProperties"]
Map args = ["size": 1000, "fields": fields.join(",")]
def lmDevices
// But first determine if the portal size is within a range that allows us to get all devices at once
def pathFlag, portalInfo, timeLimitSec, timeLimitMs
if (!skipDeviceDedupe) {
    portalInfo = lmApi.apiCallInfo("Devices", args)
    timeLimitSec = props.get("lmapi.timelimit.sec", "60").toInteger()
    timeLimitMs = (timeLimitSec) ? Math.min(Math.max(timeLimitSec, 30), 120) * 1000 : 60000
    // Allow range 30-120 sec if configured; default to 60 sec
    if (portalInfo.timeEstimateMs > timeLimitMs) {
        debugSnippet.LMDebugPrint("Estimate indicates LM API calls would take longer than time limit configured.  Proceeding with individual queries by display name for each device to add.")
        debugSnippet.LMDebugPrint("\t${portalInfo}\n\tNOTE:  Time limit is set to ${timeLimitSec} seconds.  Adjust this limit by setting the property lmapi.timelimit.sec.  Max 120 seconds, min 30 seconds.")
        pathFlag = "ind"
    } else {
        debugSnippet.LMDebugPrint("Response time indicates LM API calls will complete in a reasonable time range.  Proceeding to collect info on all devices to cross reference and prevent duplicate device creation.\n\t${portalInfo}")
        pathFlag = "all"
        lmDevices = lmApi.getPortalDevices(args)
    }
}

Map lmDevicesByName
if (pathFlag == "all" && !skipDeviceDedupe) {
    // VMware does not provide individual IP addresses, check dedupe by device name
    lmDevicesByName = lmDevices?.collectEntries { device ->
        def sysName = device?.systemProperties?.find { it -> it?.name == "system.sysname" }?.value
        def displayName = device?.systemProperties?.find { it -> it?.name == "system.displayname" }?.value
        [
                ("${sysName ?: displayName}".toString().toLowerCase()): [
                        "name"              : "${device.name}",
                        "displayName"       : (device.displayName),
                        "currentCollectorId": (device.currentCollectorId),
                        "sysName"           : (sysName)
                ]
        ]
    }
}

// Get your data and build your list of resources
List<Map> resources = []

def now = new Date()
def dateFormat = "yyyy-MM-dd'T'HH:mm:ss.s z"
TimeZone tz = TimeZone.getDefault()
Map duplicateResources = [
        "date"     : now.format(dateFormat, tz),
        "message"  : "Duplicate display names found within LogicMonitor portal wherein hostname in LM does not match hostname in Netscan output.  Refer to documentation for how to resolve name collisions using 'hostname.source' netscan property.",
        "total"    : 0,
        "resources": []
]

def edges = veloCloudSnippet.executeRequest("${veloCloudSnippet.serviceUrlV1}/enterprise/getEnterpriseEdges", JsonOutput.toJson(["enterpriseId": Integer.valueOf(enterpriseId)]))?.response
edges.each { device ->
    String hostName = device.name
    String displayName = device.name
    String displayNameToCheck = "${displayName}".toString().toLowerCase()

    // Check for existing device in LM portal with this displayName; set to false initially and update to true when dupe found
    def deviceMatch = false
    //  If customer has opted out of device deduplication checks, we skip the lookups where we determine if a match exists and proceed as false
    if (!skipDeviceDedupe) {
        if (pathFlag == "ind") {
            deviceMatch = lmApi.findPortalDeviceByProperty(hostName, args)
        } else if (pathFlag == "all") {
            deviceMatch = lmDevicesByName?.get(displayNameToCheck)
        }
    }

    if (deviceMatch) {
        // Log duplicates that would cause additional devices to be created; unless these entries are resolved, they will not be added to resources for netscan output
        if (deviceMatch.name.toString().toLowerCase() != displayNameToCheck) {
            def collisionInfo = [
                    (hostName): [
                            "Netscan" : [
                                    "hostname": hostName
                            ],
                            "LM"      : [
                                    "hostname"   : deviceMatch.name,
                                    "collectorId": deviceMatch.currentCollectorId
                            ],
                            "Resolved": false
                    ]
            ]

            // If user specified to use LM hostname on display name match, update hostname variable accordingly
            // and flag it as no longer a match since we have resolved the collision with user's input
            if (hostnameSource == "lm" || hostnameSource == "logicmonitor") {
                hostName = deviceMatch.name
                collectorId = deviceMatch.currentCollectorId
                displayName = deviceMatch.displayName
                deviceMatch = false
                collisionInfo[hostName]["Resolved"] = true
            }
            // If user specified to use netscan data for hostname, update the display name to make it unique
            // and flag it as no longer a match since we have resolved the collision with user's input
            else if (hostnameSource == "netscan") {
                // Update the resolved status before we change the displayName
                collisionInfo[hostName]["Resolved"] = true
                displayName = "${displayName - deviceMatch.name}"
                deviceMatch = false
            }

            duplicateResources["resources"].add(collisionInfo)
        }
        // Don't worry about matches where the hostname values are the same
        // These will update via normal NetScan processing and should be ignored
        else {
            deviceMatch = false
        }
    }

    List groupName = ["${rootFolder}"]

    def deviceProps = [
            "velocloud.sdwan.orchestrator.host": orchestratorHost,
            "velocloud.sdwan.edge.logical.id"  : device.logicalId,
            "velocloud.sdwan.edge.name"        : device.name,
            "velocloud.sdwan.enterprise.id"    : enterpriseId
    ]

    def serialNumber = device.serialNumber
    if (serialNumber) deviceProps.put("velocloud.sdwan.serial.number", serialNumber)

    deviceProps.putAll(sensitiveProps)

    Map resource = [
            "hostname"   : hostName,    // String
            "displayname": displayName,    // String
            "hostProps"  : deviceProps, // Map<String, String>
            "groupName"  : groupName,   // List<String>
    ]

    // Only add the collectorId field to resource map if we found a collector ID above
    if (collectorId) {
        resource["collectorId"] = collectorId
        if (duplicateResources["resources"][hostName]["Netscan"]) {
            duplicateResources["resources"][hostName]["Netscan"][0]["collectorId"] = collectorId
        }
    }

    if (!deviceMatch) {
        resources.add(resource)
    }
}

// Output validated data in JSON format
// If errors have been made in acceptable/required keys, lm.emit will throw and inform the user
emitSnippet.resource(resources, debug)

// Report devices that already exist in LM via log file named after root folder
if (duplicateResources["resources"].size() > 0) {
    def netscanDupLog = new File("../logs/NetscanDuplicates/${rootFolder.replaceAll(" ", "_")}.json")
    new File(netscanDupLog.getParent()).mkdirs()
    duplicateResources["total"] = duplicateResources["resources"].size()
    def json = JsonOutput.prettyPrint(JsonOutput.toJson(duplicateResources))
    netscanDupLog.write(json)
    if (hostnameSource) {
        debugSnippet.LMDebug("${duplicateResources["resources"].size()} devices found that were resolved with hostname.source=${hostnameSource} in netscan output.  See LogicMonitor/Agent/logs/NetscanDuplicates/${rootFolder.replaceAll(" ", "_")}.json for details.")
    } else {
        debugSnippet.LMDebug("${duplicateResources["resources"].size()} devices found that were not reported in netscan output.  See LogicMonitor/Agent/logs/NetscanDuplicates/${rootFolder.replaceAll(" ", "_")}.json for details.")
    }
}

return 0

警告: スクリプトを編集しないでください。編集された拡張スクリプトのネットスキャンはサポートされていません。LogicMonitor提供のスクリプトを編集した場合、問題が発生した場合、LogicMonitorサポートからサポート対象のスクリプトで編集内容を上書きするよう求められることがあります。拡張スクリプトのネットスキャンでは、1時間あたりのリソース作成数が制限される場合があります。1時間あたりの制限を超えて作成するには、すべてのリソースが追加されるまでネットスキャンを繰り返すようにスケジュールを設定してください。

  1.  スケジュール セクション、選択 このNetScanをスケジュールに従って実行する.
    動的環境の場合は、NetScan を 1 時間ごとに実行するようにスケジュールします。
  2. 選択する Save or 保存して実行.
    NetScan を実行した後、追加されたリソースの数の履歴、またはリソースが作成されなかった場合はエラー メッセージを確認します。

リソースを手動で追加する

  1. VeloCloud SD-WANリソースグループを作成します。詳細については、 リソース グループを追加します。  
プロパティ
velocloud.sdwan.orchestrator.hostVeloCloud Orchestrator のホスト名。
velocloud.sdwan.keyVeloCloud Orchestrator API トークン。
velocloud.sdwan.enterprise.idVeloCloud エンタープライズ ID。
system.sysname or system.displaynameエッジ名または表示名。
velocloud.sdwan.edge.logical.idVeloCloud Edge 論理 ID (正確なマッピングのために推奨)。
  1. VeloCloud SD-WAN リソース グループにリソースを追加します。 
  2. VeloCloud SD-WAN リソース グループの各リソースに次のプロパティを追加するか、設定されていることを確認します。
プロパティ
snmp.community / SNMP 資格情報リンク/パス メトリックを収集するための読み取り専用 SNMP 資格情報。

注意: Netscan を実行してもリソースが作成されない場合は、追加されたリソースの数やエラー メッセージの履歴を確認します。

リソースへのプロパティの割り当て

VeloCloud SD-WAN LogicModules が適切に機能することを保証するには、監視対象リソースに次のプロパティを割り当てます。 

プロパティ
velocloud.sdwan.orchestrator.hostVeloCloud Orchestratorポータル(例: vco1.velocloud.net).
velocloud.sdwan.key認証用の VeloCloud Orchestrator API トークン。
velocloud.sdwan.enterprise.id組織に関連付けられた VeloCloud Enterprise ID。
system.sysname or system.displaynameOrchestrator 構成に一致する Edge 名または表示名。

詳細については、を参照してください。 リソースとインスタンスのプロパティ

推奨事項: 監視には管理者アカウントを使用しないでください。データ収集専用の読み取り専用APIトークンを割り当ててください。

LogicModulesをインポートする

ExchangeからすべてのVeloCloud SD-WAN LogicModulesをインストールしてください。詳細については、「パッケージ内のLogicModules」を参照してください。これらのLogicModulesが既に存在する場合は、各モジュールの最新バージョンがインストールされていることを確認してください。 

トラブルシューティング

このスイートは、VeloCloud Orchestrator API に対する定期的なポーリングに依存しています。データギャップが発生した場合は、次の手順に従ってください。

  • Orchestrator API がコレクターからアクセス可能であり、API トークンが有効で期限切れでないことを確認します。
  • 各 Edge の SNMP 到達可能性 (UDP 161) と正しい読み取り専用資格情報を確認します。
  • 重複したデバイスが表示される場合は、 NetScan のトラブルシューティング とを確認する hostname.source 適切に設定されます。
  • API レート制限に達した場合は、ポーリング間隔を増やすか、コレクター間でポーリングをずらします。
  • オンボーディング後、実行 アクティブディスカバリー PropertySources および DataSources を使用すると、トポロジとパフォーマンスの範囲を迅速に拡大できます。

注意: NetScansは更新できません system.hostname。 NetScans は、表示名、カスタム プロパティ、およびグループの割り当てを更新できます。

NetScan のトラブルシューティング

このスイートのNetScanは、VeloCloud APIから取得した情報を使用して、ポータル内の既存のデバイスを更新できます。表示名が一致しているにもかかわらず、重複したデバイスが作成される場合があります。 system.hostname 異なります。重複を防ぐために、NetScan は LogicMonitor API を使用して既存のデバイスを照会し、競合を報告します (コレクター ログで利用可能)。

コレクターログの取得の詳細については、以下を参照してください。 LogicMonitorコレクターを使用したSyslog

重複名レポートのリソースは、次の場合を除いて追加されません。 hostname.source 次のように構成されます。

  • 「lm」または「logicmonitor」–既存の system.hostname LogicMonitorでデバイスを更新します。新しいデバイスは作成されません。
  • 「ネットスキャン」–NetScanで決定された system.hostname そして追加する - <system.hostname> 追加時の一意性を確保するために、表示名に を追加します。

注意: NetScansは変更できません system.hostname.

パッケージ内のLogicModules

LogicMonitorのVeloCloud向けパッケージは、以下のLogicModulesで構成されています。完全なカバレッジを得るには、以下のすべてをLogicMonitorプラットフォームにインポートしてください。

表示名タイプ 詳細説明
VeloCloud APIデータソースVeloCloud Orchestrator API の使用状況と応答性を監視します。
VeloCloud BGPセッションデータソースVeloCloud Edge 上の BGP セッション ステータスを監視します。
VeloCloud ヘルスデータソースEdge の健全性、稼働時間、概要ステータスを監視します。
VeloCloud リンクデータソースSNMP を使用して、ISP 回線ごとのリンク品質 (遅延、ジッター、パケット損失) を監視します。
VeloCloud パスデータソースSNMP を使用して、指定されたリンク上のエッジとゲートウェイ間のトンネル パスを監視します。
VeloCloud パフォーマンスデータソーススループットとパフォーマンス メトリックを監視します。
VeloCloud SDWANアラートログソースVeloCloud デバイスからのログとアラートを提供します。
VeloCloud_SDWAN_トポロジトポロジーソースVeloCloud SD-WAN ネットワーク トポロジを生成します。
カテゴリー_VeloCloudSDWANプロパティソース追加 VeloCloudSDWANEdge システム カテゴリと自動プロパティ。
ERI_VeloCloud_SDWAN を追加プロパティソースVeloCloud リソースの ERI を検出し、追加します。

このパッケージのデータソースによって追跡されるメトリックに静的データポイントしきい値を設定する場合、LogicMonitor はテクノロジ所有者のベスト プラクティス KPI 推奨事項に従います。

推奨事項: 環境固有の要件に合わせて、必要に応じて定義済みのしきい値を調整してください。ガイダンスについては、以下を参照してください。 データポイントの静的しきい値.

14日間フルアクセス LogicMonitor プラットフォーム