返回文章列表

Alexa語音整合Splunk實作網路自動化查詢

本文介紹如何整合Alexa語音助理與Splunk,實作語音查詢網路裝置介面狀態的自動化功能。文章涵蓋Alexa Skill開發、Splunk

網路自動化 語音助理應用

網路自動化在現代網路管理中扮演著至關重要的角色,尤其在大型網路環境中,自動化工具能有效降低人為錯誤並提高效率。本文將介紹如何結合Alexa語音助理和Splunk,實作一個語音驅動的網路裝置介面狀態查詢系統。此係統利用Alexa接收語音指令,觸發Lambda函式與Splunk API互動,執行特定查詢,並將結果以語音方式回傳給使用者。此方案結合了語音互動的便利性和Splunk強大的資料分析能力,讓網路管理人員能更輕鬆地監控網路裝置狀態。文章中將詳細說明Alexa Skill的開發、Splunk查詢的構建、Lambda函式的設計以及Python指令碼的撰寫,並提供程式碼範例和實務操作的注意事項,協助讀者快速上手並應用於實際網路環境。

自動化觸發的網頁框架:第5章 - Alexa與Splunk整合實務

概述

本章節將探討如何透過Alexa語音助手與Splunk進行整合,實作自動化查詢網路裝置介面狀態的功能。整個實作涉及Alexa Skill的開發、與Splunk API的互動以及Lambda函式的佈署。

技術實作細節

第一部分:Alexa Skill基本設定

首先,我們需要設定Alexa Skill的基本框架,這包括定義LaunchRequest處理器,用於處理使用者啟動Skill時的初始回應。

const LaunchHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
  },
  handle(handlerInput) {
    const speechText = '歡迎使用Splunk查詢工具,您可以詢問介面狀態。';
    return handlerInput.responseBuilder
      .speak(speechText)
      .withShouldEndSession(false)
      .getResponse();
  }
};

內容解密:

  • canHandle方法用於判斷是否由該處理器處理請求。
  • handle方法定義了當使用者啟動Skill時的回應內容。
  • 使用.withShouldEndSession(false)確保Alexa保持會話狀態,等待進一步的指令。

第二部分:呼叫Splunk特定查詢

接下來,我們定義了一個名為splunkintentHandler的處理器,用於根據使用者的語音指令(Intent)呼叫Splunk的查詢。

const splunkintentHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'IntentRequest' &&
           handlerInput.requestEnvelope.request.intent.name === 'splunkintent';
  },
  async handle(handlerInput) {
    var inp_status = handlerInput.requestEnvelope.request.intent.slots.status.value;
    var outputSpeech = "";
    var url = 'http://13.59.112.54/splunk/runquery';
    var data = '';
    // 根據輸入狀態構建查詢資料
    if (inp_status == "up") {
      data = {"query": "search index=\"main\" earliest=0 | where interface_name=\"Loopback45\" | dedup interface_name,router_name | where interface_status=\"up\" | stats values(interface_name) values(interface_status) by router_name | table router_name"};
    } else if (inp_status == "down") {
      data = {"query": "search index=\"main\" earliest=0 | where interface_name=\"Loopback45\" | dedup interface_name,router_name | where interface_status!=\"up\" | stats values(interface_name) values(interface_status) by router_name | table router_name"};
    }
    // 傳送POST請求至Splunk API
    var res;
    var router_array = [];
    await POSTdata(url, data)
      .then((response) => {
        res = JSON.parse(response);
        var arr_len = res.result.length;
        for (var i = 0; i < arr_len; i++) {
          router_array.push(res.result[i].router_name);
        }
      })
      .catch((err) => {
        outputSpeech = '錯誤:' + err.message;
      });
    // 構建回應語音
    var count = router_array.length;
    for (let i = 0; i < count; i++) {
      if (i === 0) {
        outputSpeech = outputSpeech + '狀態為' + inp_status + '的路由器有:' + router_array[i] + ',';
      } else if (i === count - 1) {
        outputSpeech = outputSpeech + '以及' + router_array[i] + '。';
      } else {
        outputSpeech = outputSpeech + router_array[i] + ', ';
      }
    }
    return handlerInput.responseBuilder
      .speak(outputSpeech)
      .withShouldEndSession(false)
      .getResponse();
  }
};

內容解密:

  • 該處理器根據使用者的語音指令,決定要查詢的介面狀態(up或down)。
  • 使用POSTdata函式向Splunk API傳送查詢請求,並處理傳回的JSON結果。
  • 將查詢結果轉換為自然語言,回應給使用者。

第三部分:錯誤處理

定義了一個錯誤處理器ErrorHandler,用於處理無法識別的使用者指令。

const ErrorHandler = {
  canHandle() {
    return true;
  },
  handle(handlerInput, error) {
    console.log(`錯誤處理:${error.message}`);
    return handlerInput.responseBuilder
      .speak('抱歉,我無法理解您的指令,請再試一次。')
      .reprompt('抱歉,我無法理解您的指令,請再試一次。')
      .getResponse();
  }
};

內容解密:

  • 當Alexa無法理解使用者的語音指令時,會觸發該錯誤處理器。
  • 回應一條友好的錯誤訊息,並提示使用者重複指令。

自動化觸發的網頁框架應用:持續整合

在前一章中,我們探討瞭如何建立一個網頁框架,以作為指令碼的包裝器,使其成為可被多種程式語言和工具呼叫的API。在本章中,我們將繼續深入瞭解如何利用這個網頁框架來建立可擴充套件的網路自動化解決方案,並結合人工智慧和機器人流程自動化(RPA)技術。

使用智慧觸發器進行故障修復

在大規模或高用性的環境中,工程師需要確保人為錯誤的可能性降至最低。對於服務導向的組織,即使是短暫的停機也可能導致數百萬美元的收入損失或品牌形象受損。某些任務的手動執行或硬體故障都可能導致服務中斷。

解決這一問題的方法是快速識別問題並進行自我修復。讓我們將這個問題轉化為一個具體的使用案例:在我們的環境中,確保所有路由器上的Loopback45介面始終保持啟用狀態。這是一個關鍵介面,意外關閉可能會停止流量流向路由器,或使路由器停止向特定目的地傳送Syslog或trap訊息。

步驟1:組態Splunk接收資料

首先,我們需要組態Splunk來監控本地機器上特定資料夾中的新資料。資料通常是由Python指令碼生成的,以逗號分隔的格式儲存在該資料夾中。

  1. 從設定下拉選單中選擇資料輸入
  2. 組態資料輸入以監控特定的資料夾(例如:C:\splunklogs)。

步驟2:驗證資料(樣本資料)

組態完成後,我們可以提供一些樣本資料在文字檔案中,以確定資料是否可在Splunk中檢視。這些資料應該是以逗號分隔的格式,儲存在被監控的資料夾中。

在Splunk的主搜尋頁面上,我們可以看到資料摘要顯示了一些事件。點選它將顯示詳細資訊,包括事件的來原始檔和記錄數量。

步驟3:編寫指令碼

接下來,我們編寫一個指令碼來捕捉特定路由器上每個介面的狀態,並將其寫迴檔案中。這個檔案將被Splunk接收,用於後續的分析和觸發智慧查詢。

我們的目標是從所有路由器(例如:192.168.20.1-192.168.20.4)每五分鐘取得介面統計資訊,並更新C:\splunklogs中的檔案。這樣,Splunk就可以利用這些重新整理後的資料進行驗證和歷史資料分析。

# 初始化環境,匯入必要的函式庫
import re
import netmiko
import time
import datetime
import math
from threading import Thread
import logging
import threading
from random import randrange
import itertools
import sys
import base64

#### 內容解密:
- `import re`:匯入正規表示式函式庫用於字串匹配和處理
- `import netmiko`:匯入Netmiko函式庫用於與網路裝置建立連線並執行命令
- `import time``import datetime`:匯入時間相關的函式庫用於處理時間和日期
- `from threading import Thread`:匯入執行緒函式庫用於平行執行任務
- `import logging`:匯入日誌記錄函式庫用於記錄指令碼執行過程中的事件

結合智慧查詢和自動修復

透過Splunk收集和分析介面狀態資料,我們可以使用Splunk的搜尋處理語言(SPL)編寫智慧查詢,以識別潛在問題,如Loopback45介面關閉。一旦檢測到問題,我們可以觸發自動修復流程,例如透過API呼叫重新啟用介面,以確保網路的高用性。

網路裝置介面統計資訊收集與解析系統

系統概述

本系統主要用於從網路裝置中收集介面統計資訊,並將其轉換為Splunk可分享的格式。系統透過Netmiko函式庫連線網路裝置,執行show interfaces命令來取得介面資訊,然後對輸出結果進行解析,最終將統計資料寫入指設定檔案。

設定檔解析模組

設定檔分組功能實作

class LineCheck:
    def __init__(self):
        self.state = 0
    
    def __call__(self, line):
        if line and not line[0].isspace():
            self.state += 1
        return self.state

def parse_config(config):
    rlist = []
    for _, group in itertools.groupby(config.splitlines(), key=LineCheck()):
        templist = list(group)
        if len(templist) == 1 and "!" in str(templist):
            continue
        rlist.append(templist)
    return rlist

內容解密:

  1. LineCheck類別用於追蹤組態檔案的分組狀態。
  2. parse_config函式將組態內容按分組進行切割,每個分組代表一個介面的組態資訊。
  3. 過濾掉單行且包含"!“的組態項,避免無效資訊。

介面名稱解析功能

def get_interface_name(interface_details):
    m = re.search('(^[a-zA-Z0-9/-]*) is ', interface_details)
    if m:
        return m.group(1).strip(",")
    return 'NULL'

內容解密:

  1. 使用正規表示式從介面描述資訊中提取介面名稱。
  2. 若匹配成功,傳回提取的介面名稱,否則傳回’NULL’。

介面統計資訊收集功能

def fetch_router_interface_stats(device_type, routerip, username, password, timestamp, enable_passwd=''):
    # 建立連線
    router = {
        'device_type': device_type,
        'ip': routerip,
        'username': username,
        'password': password,
        'secret': enable_passwd
    }
    try:
        net_connect = netmiko.ConnectHandler(**router)
        print(f"成功連線路由器 {routerip}")
    except Exception as ex:
        print(f"連線路由器 {routerip} 失敗")
        print(ex)
        return
    
    # 取得介面統計資訊
    router_stats = []
    interface_details = net_connect.send_command("show interfaces")
    parsed_config = parse_config(interface_details)
    
    for item in parsed_config:
        interface_name = get_interface_name('\n'.join(item))
        if interface_name in fetch_interface_summary(interface_details):
            router_stats.append(fetch_interface_stats('\n'.join(item), interface_name))
    
    # 寫入檔案
    with open(abs_filename, "a+") as text_file:
        for interface_stats in router_stats:
            text_file.write(f"{timestamp},router_name={router_hostname},interface_name={interface_stats['interface_name']},...")
            text_file.write('\n')
    
    net_connect.disconnect()
    return

內容解密:

  1. 建立與路由器的連線,並執行show interfaces命令取得介面資訊。
  2. 解析介面資訊並提取每個介面的統計資料。
  3. 將統計資料寫入指定的檔案中。

介面統計資訊解析功能

def fetch_interface_stats(interface_details, interface_name):
    stats = {}
    # 解析介面狀態、錯誤計數等資訊
    m = re.search('([\d]+) interface resets', interface_details)
    if m:
        stats['interface_resets'] = int(m.group(1))
    else:
        stats['interface_resets'] = -1
    
    # 其他統計資訊解析...
    
    return stats

內容解密:

  1. 使用正規表示式解析介面的各種統計資訊,如重置次數、輸出錯誤等。
  2. 將解析結果存入字典並傳回。

系統設計考量

  • 使用多執行緒技術提高資料收集效率。
  • 對網路裝置的連線進行例外處理,確保系統的穩定性。
  • 資料解析採用正規表示式,提高了資料提取的靈活性和準確性。