Cisco カタリスト センター

最終更新日: 05 年 2024 月 XNUMX 日

LogicMonitor の Cisco Catalyst Center パッケージは、Cisco Catalyst Center Intent API(旧称 Cisco DNA Center)を利用して、Cisco ワイヤレス アクセス ポイント、ワイヤレス LAN コントローラ(「WLC」)、スイッチ、およびルータを検出および監視します。この監視パッケージは、Catalyst Center の問題を LM ログに送信しながら、LogicMonitor が各問題を関連する LogicMonitor リソースに関連付けながら、重要な健全性とパフォーマンスのメトリクスを監視して警告するように設計されています。 

Cisco Catalyst Intent API の詳細については、次を参照してください。 Cisco DNA Center REST API の概要 シスコから。

Note:これらのモジュールは、Cisco Catalyst Center デバイスを個別の LogicMonitor リソースとして検出および監視し、Cisco DNA Center(レガシー)モジュールへのインプレース アップグレードではありません。

要件

  • コレクター バージョン 32.400 以降
  • リソースに読み取り専用アクセスが設定された Cisco Catalyst Center のユーザ名とパスワード
  • Cisco Catalyst Center と通信できる十分なサイズの LogicMonitor Collector
  • Cisco Catalyst Center によって管理されるデバイス

モニタリングにリソースを追加する

Cisco Catalyst Center で管理されるワイヤレス アクセス ポイントとワイヤレス コントローラ リソースをモニタリングにオンボードするには 2 つの方法が使用できます。 Advanced NetScan はオンボーディングに推奨される方法ですが、リソースを手動で監視に追加することもできます。 NetScan の詳細については、次を参照してください。 ネットスキャンとは.

  • (推奨) 高度な NetScan
    NetScan の詳細については、次を参照してください。 ネットスキャンとは.
  • リソースを手動で追加する

高度な NetScan を使用してリソースを追加する

リソースは、拡張 NetScan スクリプトを使用して自動的に追加できます。 詳細については、「」を参照してください。 強化されたスクリプト ネットスキャン.

  1. あなたの中で ロジックモニターポータル > モジュール > 応募者と、Cisco Catalyst Center モジュールをインストールします。モジュールのリストについては、「パッケージ内の LogicModules」を参照してください。
  2. MFAデバイスに移動する  リソース > Add > 複数のデバイス > 高度なネットスキャンを選択します。 高度な NetScan を追加する ページが表示されます。
  3. この NetScan に関連付ける名前を入力します。たとえば、「Cisco Catalyst Center デバイス」です。
  4. NetScan を実行するコレクタを選択します。詳細については、「」を参照してください。 コレクターの割り当て in 強化されたスクリプト ネットスキャン.
  5. 選択 強化されたスクリプト NetScan   方法 ドロップダウンリスト。
  6. 「拡張スクリプト」セクションから、次を選択します。 デバイスの資格情報 > このスキャンにカスタム資格情報を使用する.
  7. NetScan に必要な Cisco Catalyst Center DNA API クレデンシャルを提供する次のプロパティを追加し、NetScan がリソースを作成および編成する方法と場所を変更します。
プロパティ必須
cisco.catalyst.center.userREST API のユーザー名。有り
cisco.catalyst.center.passREST API パスワード。有り
cisco.catalyst.center.hostCisco Catalyst Center デバイスの IP または FQDN。有り
lmaccess.id  
or
ロジックモニター.アクセス.id
ポータルにリソースを追加する前に NetScan で重複リソースを検索するための LogicMonitor API アクセス ID。 ポータル監視の詳細については、次を参照してください。 LogicMonitorポータルモニタリング.有り

Skip.device.dedupe が設定されている場合は不要です。
lmaccess.key 
or
ロジックモニター.アクセス.キー
ポータルにリソースを追加する前に NetScan で重複リソースを検索するための LogicMonitor API キー。 ポータル監視の詳細については、次を参照してください。 LogicMonitorポータルモニタリング.有り

Skip.device.dedupe が設定されている場合は不要です。
cisco.catalyst.center.フォルダこの NetScan が作成するか、すでに存在する場合は使用する LogicMonitor リソース グループの名前。値には、ネストされた子フォルダー (たとえば、フォルダー/フォルダー/フォルダー) を指定できます。デフォルトは「Cisco Catalyst Center」です。動的デバイス グループは NetScans によって追加されないため、これを動的デバイス グループに割り当てないでください。
詳細については、を参照してください。 デバイスグループの概要.
いいえ
cisco.catalyst.center.nameこの NetScan が作成するか、すでに存在する場合は使用する LogicMonitor リソース グループの名前。デフォルトは「Cisco Catalyst Center」です。いいえ
ホスト名.ソースNetScan で使用されるホスト名のソースを選択できます。これは、既存のリソースに競合が見つかった場合に、重複したデバイスの作成を防ぐのに役立ちます。いいえ
スキップ.device.dedupeデバイスの重複排除チェックをスキップできるため、LogicMonitor API 認証情報が不要になります。いいえ
cisco.catalyst.center.collector.sites.csvサイト名、コレクタ ID、およびサイト フォルダ名を含む CSV ファイルのパス。 CSV ファイルは次のパスに配置する必要があります: /usr/local/logicmonitor/agent/bin ディレクトリ (Linux) または C:\Program Files\LogicMonitor\Agent\bin ディレクトリ (Windows)いいえ
cisco.catalyst.service.urlAPI 呼び出しを行うために使用される URL。デフォルトは「/dna/intent/api/v1」いいえ
cisco.catalyst.center.sites考慮する Cisco Catalyst Center サイト ID のカンマ区切りのリスト。いいえ
cisco.catalyst.center.devicefamilies検討すべき Cisco Catalyst Center Wireless デバイスのファミリー。デフォルトは UNIFIED_AP、WIRELESS_CONTROLLER、SWITCHES_AND_HUBS、および ROUTER です。いいえ
  1. 選択 Groovyスクリプトを埋め込む 次のスクリプトを埋め込みます。

警告: スクリプトを編集しないでください。編集された拡張スクリプト NetScan はサポートされていません。 LogicMonitor が提供するスクリプトを編集した場合、問題が発生した場合、LogicMonitor サポートはサポートされているスクリプトで編集内容を上書きするよう要求する場合があります。

/*******************************************************************************
 * © 2007-2024 - LogicMonitor, Inc. All rights reserved.
 ******************************************************************************/

import com.logicmonitor.common.sse.utils.GroovyScriptHelper as GSH
import com.logicmonitor.mod.Snippets
import com.santaba.agent.AgentVersion
import java.text.DecimalFormat
import groovy.json.JsonOutput
import groovy.json.JsonSlurper

// To run in debug mode, set to true
Boolean debug = false

// To enable logging, set to true
Boolean 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
}

String user = props.get("cisco.catalyst.center.user", props.get("cisco.dna.center.user"))
String pass = props.get("cisco.catalyst.center.pass", props.get("cisco.dna.center.pass"))
String catalystCenterHost = props.get("cisco.catalyst.center.host", props.get("cisco.dna.center.host"))
if (!user) {
    throw new Exception("Must provide cisco.catalyst.center.user to run this script.  Verify necessary credentials have been provided in Netscan properties.")
}
if (!pass) {
    throw new Exception("Must provide cisco.catalyst.center.pass credentials to run this script.  Verify necessary credentials have been provided in Netscan properties.")
}
if (!catalystCenterHost) {
    throw new Exception("Must provide cisco.catalyst.center.host to run this script.  Verify necessary properties have been provided in Netscan properties.")
}

def logCacheContext = "${catalystCenterHost}::cisco-catalyst-center"
Boolean skipDeviceDedupe = props.get("skip.device.dedupe", "false").toBoolean()
String hostnameSource    = props.get("hostname.source", "")?.toLowerCase()?.trim()

Integer collectorVersion = AgentVersion.AGENT_VERSION.toInteger()
 
// Bail out early if we don't have the correct minimum collector version to ensure netscan runs properly
if (collectorVersion < 32400) {
    def formattedVer = new DecimalFormat("00.000").format(collectorVersion / 1000)
    throw new Exception("Upgrade collector running netscan to 32.400 or higher to run full featured enhanced netscan. Currently running version ${formattedVer}.")
}
 
// Bail out early if we don't have the correct minimum collector version to ensure netscan runs properly
if (collectorVersion < 32400) {
    def formattedVer = new DecimalFormat("00.000").format(collectorVersion / 1000)
    throw new Exception("Upgrade collector running netscan to 32.400 or higher to run full featured enhanced netscan. Currently running version ${formattedVer}.")
}

def modLoader = GSH.getInstance()._getScript("Snippets", Snippets.getLoader()).withBinding(getBinding())
def emit        = modLoader.load("lm.emit", "1")
def lmDebugSnip = modLoader.load("lm.debug", "1")
def lmDebug     = lmDebugSnip.debugSnippetFactory(out, debug, log, logCacheContext)
def httpSnip    = modLoader.load("proto.http", "0")
def http        = httpSnip.httpSnippetFactory(props)
def cacheSnip   = modLoader.load("lm.cache", "0")
def cache       = cacheSnip.cacheSnippetFactory(lmDebug, logCacheContext)
// 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, http, lmDebug)
}
def ciscoCatalystCenterSnip = modLoader.load("cisco.catalyst.center", "0")
def ciscoCatalystCenter     = ciscoCatalystCenterSnip.ciscoCatalystCenterSnippetFactory(props, lmDebug, cache, http)

String orgDisplayname    = props.get("cisco.catalyst.center.name") ?: "Cisco Catalyst Center"
String orgFolder         = props.get("cisco.catalyst.center.folder") ? props.get("cisco.catalyst.center.folder") + "/" : ""
String serviceUrl        = props.get("cisco.catalyst.service.url") ?: "https://${ciscoCatalystCenter.host}/dna/intent/api/v1"
def sitesWhitelist       = props.get("cisco.catalyst.center.sites")?.tokenize(",")?.collect{ it.trim() }
def deviceFamilies       = props.get("cisco.catalyst.center.devicefamilies")?.tokenize(",")?.collect{ it.trim() }
def collectorSitesCSV    = props.get("cisco.catalyst.center.collector.sites.csv")
def collectorSiteInfo
if (collectorSitesCSV) collectorSiteInfo = processCollectorSiteInfoCSV(collectorSitesCSV)

// Get information about devices that already exist in LM portal
List fields = ["name", "currentCollectorId", "displayName"]
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) {
        lmDebug.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.")
        lmDebug.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 {
        lmDebug.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)
    }
}

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 device names and display names, keyed by display name that would be assigned by the netscan, found within LogicMonitor portal.  Refer to documentation for how to resolve name collisions using 'hostname.source' netscan property.",    "total" : 0,
    "total" : 0,
    "resources" : []
]

// Gather data from cache if running in debug otherwise make API requests
def deviceHealth
if (debug) {
    deviceHealth = cache.cacheGet("${ciscoCatalystCenter.host}:deviceHealth")
    if (deviceHealth) {
        deviceHealth = ciscoCatalystCenter.slurper.parseText(deviceHealth).values()
    } else {
        deviceHealth = ciscoCatalystCenter.httpGet("device-health")?.response
        if (deviceHealth) deviceHealth = ciscoCatalystCenter.slurper.parseText(JsonOutput.toJson(deviceHealth))        
    }
} else {
    deviceHealth = ciscoCatalystCenter.httpGet("device-health")?.response
    if (deviceHealth) deviceHealth = ciscoCatalystCenter.slurper.parseText(JsonOutput.toJson(deviceHealth))
}

// Device health data is required; we cannot proceed without it
if (!deviceHealth) {
    throw new Exception("Error occurred during /device-health HTTP GET: ${deviceHealth}.")
}

// Gather data from cache if running in debug otherwise make API requests
def networkDevice
if (debug) {
    networkDevice = cache.cacheGet("${ciscoCatalystCenter.host}:networkDevice")
    if (networkDevice) {
        networkDevice = ciscoCatalystCenter.slurper.parseText(networkDevice).values()
    } else {
        networkDevice = ciscoCatalystCenter.httpGet("network-device")?.response
        if (networkDevice) networkDevice = ciscoCatalystCenter.slurper.parseText(JsonOutput.toJson(networkDevice))        
    }
} else {
    networkDevice = ciscoCatalystCenter.httpGet("network-device")?.response
    if (networkDevice) networkDevice = ciscoCatalystCenter.slurper.parseText(JsonOutput.toJson(networkDevice))
}

// Network device data is required; we cannot proceed without it
if (!networkDevice) {
    throw new Exception("Error occurred during /network-device HTTP GET: ${networkDevice}.")
}

// Gather data from cache if running in debug otherwise make API requests
def sites
if (debug) {
    sites = cache.cacheGet("${ciscoCatalystCenter.host}:site")
    if (sites) {
        sites = ciscoCatalystCenter.slurper.parseText(sites).values()
    } else {
        sites = ciscoCatalystCenter.httpGet("site")?.response
        if (sites) sites = ciscoCatalystCenter.slurper.parseText(JsonOutput.toJson(sites))        
    }
} else {
    sites = ciscoCatalystCenter.httpGet("site")?.response
    if (sites) sites = ciscoCatalystCenter.slurper.parseText(JsonOutput.toJson(sites))
}

// Sites data is required; we cannot proceed without it
if (!sites) {
    throw new Exception("Error occurred during /site HTTP GET: ${sites}.")
}

// Physical topology data is required; we cannot proceed without it
def physicalTopology = ciscoCatalystCenter.httpGet("topology/physical-topology")
if (!physicalTopology) {
    throw new Exception("Error occurred during /topology/physical-topology HTTP GET: ${physicalTopology}.")
}

physicalTopology = ciscoCatalystCenter.slurper.parseText(JsonOutput.toJson(physicalTopology))
def ipToSiteId = [:]
physicalTopology.response.nodes.each { node ->
    def ip = node.ip
    def siteId = node.additionalInfo?.siteid
    if (ip && siteId) ipToSiteId.put(ip, siteId)
}


if (deviceFamilies) {
    deviceHealth = deviceHealth.findAll { deviceFamilies.contains(it.deviceFamily) }
}

deviceHealth.each { device ->
    def ip = device.ipAddress
    def displayName = device.name
    def siteInfo = sites.find { it.id == ipToSiteId[device.ipAddress]}
    def siteId = siteInfo?.id
    def siteName = siteInfo?.name
    
    def associatedWlcIp = networkDevice.find { it.managementIpAddress == ip }?.associatedWlcIp

    // Verify this site should be included based on customer whitelist configuration
    if (sitesWhitelist != null && !sitesWhitelist.contains(siteId)) return

    // 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.findPortalDevice(displayName, args)
            if (!deviceMatch) deviceMatch = lmApi.findPortalDeviceByName(ip, args)
        }
        else if (pathFlag == "all") {
            deviceMatch = lmApi.checkExistingDevices(displayName, lmDevices)
            if (!deviceMatch) deviceMatch = lmApi.checkExistingDevicesByName(ip, lmDevices)
        }
    }
    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 (ip != deviceMatch.name) {
            def collisionInfo = [
                (displayName) : [
                    "Netscan" : [
                        "hostname"    : ip
                    ],
                    "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") {
                ip = deviceMatch.name
                deviceMatch = false
                collisionInfo[displayName]["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[displayName]["Resolved"] = true
                displayName = "${displayName} - ${ip}"
                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
        }
    }

    // Verify we have minimum requirements for device creation
    if (ip && siteId && siteName) {
        def deviceProps = [
            "cisco.catalyst.center.host"            : catalystCenterHost,
            "cisco.catalyst.center.user"            : user,
            "cisco.catalyst.center.pass"            : pass,
            "cisco.catalyst.center.site"            : emit.sanitizePropertyValue(siteName),
            "cisco.catalyst.center.site.id"         : emit.sanitizePropertyValue(siteId)        ]

        if (device.deviceFamily == "UNIFIED_AP") {
            deviceProps.put("system.categories", "CiscoCatalystAccessPoint")
            deviceProps.put("cisco.catalyst.center.associatedWlcIp", emit.sanitizePropertyValue(associatedWlcIp))
        } else if (device.deviceFamily == "WIRELESS_CONTROLLER") {
            deviceProps.put("system.categories", "CiscoCatalystWLC")
        } else if (device.deviceFamily == "SWITCHES_AND_HUBS") {
            deviceProps.put("system.categories", "CiscoCatalystSwitch")
        } else if (device.deviceFamily == "ROUTERS") {
            deviceProps.put("system.categories", "CiscoCatalystRouter")
        }

        if (device.location) {
            try {
                def address = device.location.tokenize("/")[-2..-1]?.join(" ")?.tokenize("-")[1..-1]?.join(" ")
                if (address) deviceProps.put("location", address)    
            } catch (Exception e) {
                lmDebug.LMDebugPrint("Exception parsing address: ${e}")
            }
        }

        if (sitesWhitelist != null) deviceProps.put("cisco.catalyst.center.sites", emit.sanitizePropertyValue(sitesWhitelist))

        // Set group and collector ID based on user CSV inputs if provided
        def collectorId
        Map resource
        if (collectorSiteInfo) {
            collectorId = collectorSiteInfo[siteId]["collectorId"]
            def folder      = collectorSiteInfo[siteId]["folder"]
            resource = [
                "hostname"    : ip,
                "displayname" : displayName,
                "hostProps"   : deviceProps,
                "groupName"   : ["${orgFolder}${folder}/${siteName}"],
                "collectorId" : collectorId
            ]
            resources.add(resource)
        } else {
            resource = [
                "hostname"    : ip,
                "displayname" : displayName,
                "hostProps"   : deviceProps,
                "groupName"   : ["${orgFolder}${orgDisplayname}/${siteName}"]
            ]
            resources.add(resource)
        }

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

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

lmDebug.LMDebugPrint("Duplicate Resources:")
duplicateResources.resources.each {
    lmDebug.LMDebugPrint("\t${it}")
}

emit.resource(resources, debug)

return 0

/**
 * Processes a CSV with headers collector id, folder, and site
 * @param filename String
 * @return collectorInfo Map with site id as key and Map of additional attributes as value
*/
Map processCollectorSiteInfoCSV(String filename) {
    // Read file into memory and split into list of lists
    def csv = newFile(filename, "csv")
    def rows = csv.readLines()*.split(",")
    def collectorInfo = [:]

    // Verify whether headers are present and expected values
    // Sanitize for casing and extra whitespaces while gathering headers
    def maybeHeaders = rows[0]*.toLowerCase()*.trim()
    if (maybeHeaders.contains("collector id") && maybeHeaders.contains("folder") && maybeHeaders.contains("site")) {
        Map headerIndices = [:]
        maybeHeaders.eachWithIndex{ val, i ->
            headerIndices[val] = i
        }
        // Index values for headers to ensure we key the correct index regardless of order
        def ni = headerIndices["site"]
        def ci = headerIndices["collector id"]
        def fi = headerIndices["folder"]

        // Remove headers from dataset
        def data = rows[1..-1]
        // Build a map indexed by site for easy lookups later
        data.each{ entry ->
            collectorInfo[entry[ni]] = [
                    "collectorId" : entry[ci],
                    "folder"      : entry[fi]
                ]
        }
    }
    // Bail out early if we don't have the expected headers in the provided CSV
    else {
        throw new Exception(" Required headers not provided in CSV.  Please provide \"Collector ID\", \"Network Organization Device Name\", \"Folder Name, \"and Network (case insensitive).  Headers provided: \"${rows[0]}\"")
    }

    return collectorInfo
}

/**
 * Sanitizes filepath and instantiates File object
 * @param filename String
 * @param fileExtension String
 * @return File object using sanitized relative filepath
*/
File newFile(String filename, String fileExtension) {
    // Ensure relative filepath is complete with extension type
    def filepath
    if (!filename.startsWith("./")) {
        filepath = "./${filename}"
    }
    if (!filepath.endsWith(".${fileExtension}")) {
        filepath = "${filepath}.${fileExtension}"
    }

    return new File(filepath)
}
  1. 「スケジュール」セクションで、次を選択します。 このNetScanをスケジュールに従って実行する。 動的環境の場合、NetScan を XNUMX 時間ごとに実行するようにスケジュールできます。
  2. 選択 Save or 保存して実行.

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

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

  1. Cisco Catalyst Center デバイス グループを作成します。詳細については、「」を参照してください。 デバイスグループの追加.
  2. デバイスを Cisco Catalyst Center 組織グループに追加します。
  3. 次のプロパティがリソース上または Cisco Catalyst Center リソース グループの下に設定されていることを追加または確認します。プロパティの設定の詳細については、を参照してください。 リソースとインスタンスのプロパティ.
プロパティ
システム カテゴリCiscoCatalystAccessPoint、CiscoCatalystWLC、CiscoCatalystSwitch、または CiscoCatalystRouter。
cisco.catalyst.center.userREST API のユーザー名。
cisco.catalyst.center.passREST API パスワード。
cisco.catalyst.center.hostCisco Catalyst Center IP
or 
FQDN

LogicModulesのインポート

LogicMonitor パブリック リポジトリから、すべての Cisco Catalyst Center LogicModule をインポートします。

これらの LogicModule がすでに存在する場合は、最新バージョンであることを確認してください。

LogicModule がインポートされると、データ収集が自動的に開始されます。モジュールのインポートの詳細については、を参照してください。 LMエクスチェンジ.

トラブルシューティング

このパッケージは、コレクタ スクリプト キャッシュに依存して、Cisco Catalyst Center API モジュールからデータを継続的に取得して保存し、レート制限の制約を最小限に抑えます。詳細については、を参照してください。 コレクタースクリプトのキャッシュ。データ ギャップが発生した場合は、Cisco_Catalyst_Center_API が正常に実行されていることを確認し、LogicMonitor_Collector_ScriptCache データソースでスクリプト キャッシュの健全性を確認します。

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

このスイートの NetScan は、ポータル内の既存のデバイスを更新して、Cisco API から取得した関連情報を追加できます。 また、表示名は同じでも system.hostname の値が異なるという競合が存在する場合、NetScan がポータル内に重複したデバイスを作成する可能性があります。 デバイスが適切に更新され、重複したデバイスが作成されないように、この NetScan は LogicMonitor の API を使用して既存のデバイスをクエリし、検出された名前の競合を報告します。 このファイルにはコレクター ログからアクセスできます。 コレクタ ログの取得の詳細については、「」を参照してください。 コレクターログ–LogicMonitorへのログの送信.

NetScan がプロパティで構成されていない限り、このレポート内のデバイスは NetScan 出力の一部として LogicMonitor に報告されません。 hostname.source。 このプロパティを使用すると、ユーザーは、NetScan 出力で使用されるホスト名のソースを選択することによって、検出された名前の競合を解決できます。 考えられる XNUMX つのホスト名ソースは、次の値によって決まります。

  • 「lm」または「logicmonitor」 名前が競合しているデバイスは、LogicMonitor の既存の system.hostname を使用して、ポータル内のデバイスが NetScan を使用して更新されるようにします。 この設定では新しいデバイスは作成されません。
  • 「netscan」 名前が競合しているデバイスは、NetScan スクリプトで決定された system.hostname を維持し、追加するように報告された表示名を更新します。 - <system.hostname> 一意であり、ポータルに追加できることを確認するためです。 このオプションは、厳密な命名規則がなく、同じ表示名を持つ複数のデバイスがある場合に役立ちます。

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

パッケージ内のLogicModules

Cisco Catalyst Center 用の LogicMonitor パッケージは、次の LogicModules で構成されています。完全にカバーするには、次のすべての LogicModule を LogicMonitor プラットフォームにインポートします。

Cisco Catalyst Center 用の LogicMonitor パッケージは、次の LogicModules で構成されています。完全にカバーするには、次のすべての LogicModule を LogicMonitor プラットフォームにインポートします。

表示名タイプ説明
addCategory_Cisco_Catalyst_Center_Deviceプロパティソースシステム カテゴリ CiscoCatalystAccessPoint または CiscoCatalystWLC と、関連するデバイス情報を含む自動プロパティを追加します。
addERI_Cisco_Catalyst_Center_DeviceプロパティソースCisco Catalyst Center リソースの ERI を検出して追加します。
Cisco_Catalyst_Center_TopologyトポロジーソースCisco Catalyst Center トポロジをマップします。
Catalyst アクセス ポイントの健全性データソースCatalyst Center が管理するアクセス ポイントの健全性。
Catalyst アクセス ポイントのパフォーマンスデータソースCatalyst Center 管理のアクセス ポイントのパフォーマンス。
Catalyst アクセス ポイント無線データソースCatalyst Center 管理のアクセス ポイントの無線帯域モニタリング。
Cisco_Catalyst_Center_APIデータソースCatalyst Center API の使用状況を監視します。
Cisco_Catalyst_WLCHealthデータソースCatalyst Center が管理するワイヤレス LAN コントローラの健全性。
Cisco_Catalyst_WLCPerformanceデータソースCatalyst Center で管理されるワイヤレス LAN コントローラのパフォーマンス。
触媒スイッチの健全性データソースCatalyst Center が管理するスイッチの健全性。
触媒スイッチのパフォーマンスデータソースCatalyst Center 管理のスイッチのパフォーマンス。
Catalyst ルーターの健全性データソースCatalyst Center が管理するルーターの健全性。
Catalyst ルーターのパフォーマンスデータソースCatalyst Center が管理するルーターのパフォーマンス。
Cisco_Catalyst_Center_IssuesログソースCisco ネットワーク デバイスのログを提供します。

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

推奨事項: 必要に応じて、環境固有のニーズに合わせてこれらの事前定義されたしきい値を調整します。 データポイントのしきい値の調整の詳細については、を参照してください。 データポイントの静的しきい値の調整.

記事上で