華為云計算 云知識 教你如何將華為云CDN日志轉(zhuǎn)存到OBS
教你如何將華為云CDN日志轉(zhuǎn)存到OBS

 【最新活動】

CDN記錄了所有域名(包括已刪除域名,如果您開通了企業(yè)項目,則已刪除域名不支持此功能)被網(wǎng)絡(luò)用戶訪問的詳細日志,您可以通過CDN控制臺查看和下載最近30天的日志,對您的業(yè)務(wù)資源被訪問情況進行詳細分析。

日志轉(zhuǎn)存儲服務(wù)是華為云CDN配合 函數(shù)工作流 ,將CDN日志存儲到OBS桶,可以幫助您將日志存儲更長的時間,便于您基于長時間的日志做出自定義的數(shù)據(jù)分析,有助于您更好地了解您CDN的服務(wù)質(zhì)量,以及您的終端客戶的訪問詳情,提高您的業(yè)務(wù)決策能力。

本文以Python3.6為例,為您介紹通過API創(chuàng)建FunctionGraph函數(shù)和Timer觸發(fā)器,實現(xiàn)定時將CDN日志轉(zhuǎn)存到OBS。

 

CDN日志轉(zhuǎn)存到OBS需具備的前提條件

暫時僅支持日志轉(zhuǎn)存到北京四的OBS桶,請您提前準備好位于北京四的OBS桶。

詳細操作步驟如下:

創(chuàng)建委托

登錄華為云控制臺,在左側(cè)導(dǎo)航欄,選擇管理與監(jiān)管> 統(tǒng)一身份認證 服務(wù)。

在左側(cè)導(dǎo)航欄,選擇“委托”頁簽,單擊右上方的“+ 創(chuàng)建委托”。

在創(chuàng)建委托頁面,按照如下參數(shù)設(shè)置委托。

委托名稱:FG_TO_CDN。

委托類型:云服務(wù)。

云服務(wù):函數(shù)工作流FunctionGraph。

持續(xù)時間:永久。

單擊“下一步”,進入為“FG_TO_CDN”委托配置權(quán)限界面。

權(quán)限選擇:OBS OperateAccess 、CDN LogsReadOnlyAccess。

單擊“下一步”,配置作用范圍。

作用范圍:全局服務(wù)。

單擊“確認”,完成委托配置。

 

準備函數(shù)工作流環(huán)境

登錄華為云控制臺,在左側(cè)導(dǎo)航欄,選擇計算>函數(shù)工作流,region選擇“北京四”。

單擊右上方“創(chuàng)建函數(shù)”,進入創(chuàng)建函數(shù)界面。

選擇模板:創(chuàng)建空白函數(shù)。

輸入函數(shù)名稱:cdn_to_obs(可自定義)。

所屬應(yīng)用:選擇默認的“default”。

委托名稱:選擇已創(chuàng)建好的委托“FG_TO_CDN” 。

企業(yè)項目:選擇“default”。

運行時語言:選擇“Python 3.6”。

代碼上傳方式:選擇“默認代碼”。

單擊“創(chuàng)建函數(shù)”,進入代碼編輯界面,將代碼示例的代碼內(nèi)容貼入在線IDE。

說明:如果有多個域名的日志需要轉(zhuǎn)存,您需要分別為每個域名創(chuàng)建一個函數(shù)工作流。

單擊“配置”,進入函數(shù)配置界面。

執(zhí)行超時時間:函數(shù)運行的超時時間,超時的函數(shù)將被強行停止,建議設(shè)置為900。

說明:如果您發(fā)現(xiàn)轉(zhuǎn)存的日志數(shù)量不對,請向“函數(shù)工作流”服務(wù)提工單,增大執(zhí)行超時時間。

url :https://cdn.myhuaweicloud.com/v1.0/cdn/logs(CDN日志下載的url)。

domain_name :com(需要轉(zhuǎn)存日志的 CDN加速 域名)。

obsAddress :com(用于存日志的OBS桶域名)。

destBucket :******(用于存日志的OBS桶名稱)。

單擊右上方“保存”,完成設(shè)置。

創(chuàng)建“觸發(fā)器。在函數(shù)配置界面選擇“觸發(fā)器”,單擊右側(cè)“創(chuàng)建觸發(fā)器”。

觸發(fā)器類型:定時觸發(fā)器 (TIMER)。

定時器名稱:自定義的定時器名稱,例如:Timer-0001。

觸發(fā)規(guī)則:Cron表達式。

Cron表達式:0 0 8 * * ?(每天早上8點執(zhí)行一次日志轉(zhuǎn)存儲)。

是否開啟:開啟。

單擊“確定”,完成定時觸發(fā)器設(shè)置。

創(chuàng)建測試事件。在函數(shù)配置界面,單擊右上角“請選擇測試事件”下拉框,選擇“配置測試事件”。

配置測試事件:創(chuàng)建新的測試事件。

事件模板:空白模板。

事件名稱:test。

測試事件:{"message":"CDNLog-OBS"}。

單擊“保存”,完成測試事件創(chuàng)建。

測試函數(shù)。在函數(shù)詳情頁面,單擊右上角“請選擇測試事件”下拉框,選擇“test”,單擊“測試”。

 

查看配置是否成功

登錄華為云控制臺,在左側(cè)導(dǎo)航欄,選擇存儲> 對象存儲服務(wù) OBS。

單擊您存儲日志的桶,在左側(cè)導(dǎo)航欄選擇“對象”。

訪問路徑:文件夾(桶名稱)>文件夾(加速域名)>文件夾(日志日期)>日志內(nèi)容。

說明:當(dāng)前代碼示例僅支持轉(zhuǎn)存當(dāng)前時間前一日的日志,如果您需要轉(zhuǎn)存日志的加速域名前一日沒有日志產(chǎn)生,則OBS桶側(cè)不會產(chǎn)生相關(guān)文件。

OBS桶將對轉(zhuǎn)存到桶里的日志收費,具體收費規(guī)則請參考計費說明。

 

停止日志轉(zhuǎn)存服務(wù)

. 登錄華為云控制臺,在左側(cè)導(dǎo)航欄,選擇“計算>函數(shù)工作流”,region選擇“北京四”。

在左側(cè)導(dǎo)航欄選擇“函數(shù)”>“函數(shù)列表”,選中2中創(chuàng)建的函數(shù)名。

在函數(shù)詳情頁選擇“觸發(fā)器”。

單擊“停用”,完成配置。

 

代碼示例

代碼如下所示:

# -*- coding:utf-8 -*-

import requests

import datetime

import time

import os

import sys

import json

 

from com.obs.client.obs_client import ObsClient

 

from urllib.parse import urlparse

 

if sys.version_info.major == 2 or not sys.version > '3':

    import httplib

else:

    import http.client as httplib

 

current_file_path = os.path.dirname(os.path.realpath(__file__))

# Adds the current path to search paths to import third-party libraries.

sys.path.append(current_file_path)

 

TEMP_ROOT_PATH = "/tmp/"  # Downloads a file from OBS to this directory.

region = 'china'  # This parameter does not need to be changed and will be used when FunctionGraph accesses OBS.

secure = True  # This parameter does not need to be changed and will be used when FunctionGraph accesses OBS.

signature = 'v4'  # This parameter does not need to be changed and will be used when FunctionGraph accesses OBS.

port = 443  # This parameter does not need to be changed and will be used when FunctionGraph accesses OBS.

path_style = True  # This parameter does not need to be changed and will be used when FunctionGraph accesses OBS.

 

 

def handler(event, context):

    logger = context.getLogger()

    queryDate = context.getUserData('queryDate')

    if queryDate is None:

        yesterday = datetime.date.today() + datetime.timedelta(-1)

        queryDate = yesterday.strftime("%Y-%m-%d")

        timeStamp = int(time.mktime(yesterday.timetuple()) * 1000)

    else:

        date = datetime.datetime.strptime(queryDate, "%Y-%m-%d")

        timeStamp = int(time.mktime(date.timetuple()) * 1000)

 

    pageSize = 20

    pageNumber = 1

 

    requests.packages.urllib3.disable_warnings()

    start(context, queryDate, timeStamp, pageSize, pageNumber)

 

 

def start(context, queryDate, timeStamp, pageSize, pageNumber):

    logger = context.getLogger()

    logUrl = context.getUserData('url')

    domainName = context.getUserData('domain_name')

 

    params = {'query_date': timeStamp, 'domain_name': domainName, 'page_size': pageSize, 'page_number': pageNumber, 'enterprise_project_id':'ALL'}

    headers = {'Content-Type': 'application/json;charset=UTF-8', 'X-Auth-Token': context.getToken()}

    res = requests.get(logUrl, params=params, headers=headers, verify=False)

    if res.status_code != 200:

        logger.info("query log urls: " + res.url + ", error: " + res.text)

        return ("query log urls: " + res.url + ", error: " + res.text)

 

    resJson = json.loads(res.text)

    logger.info(res.text)

    total = resJson['total']

    i = 0

    for val in resJson['logs']:

        i += 1

        logger.info(val["link"])

 

        url = urlparse(val["link"])

        netlocs = url.netloc.split(":")

        conn = httplib.HTTPConnection(netlocs[0], int(netlocs[1]))

        conn.request('GET', url.path + "?" + url.query)

        objName = os.path.join(val["domain_name"], queryDate, val["name"])

        put_content_to_obs(context, objName, conn.getresponse())

 

    if pageSize * pageNumber < total:

        start(context, queryDate, timeStamp, pageSize, pageNumber + 1)

 

 

def put_content_to_obs(context, objName, content):

    ak = context.getAccessKey()

    sk = context.getSecretKey()

    obsAddress = context.getUserData('obsAddress')

    destBucket = context.getUserData('destBucket')

    TestObs = ObsClient(access_key_id=ak, secret_access_key=sk,

                        is_secure=secure, server=obsAddress, signature=signature, path_style=path_style, region=region,

                        ssl_verify=False, port=port,

                        max_retry_count=5, timeout=20)

    resp = TestObs.putContent(destBucket, objName, content=content)

    if resp.status < 300:

        print('requestId:', resp.requestId)

    else:

        print('errorCode:', resp.errorCode)

        print('errorMessage:', resp.errorMessage)

 

希望以上內(nèi)容對你的業(yè)務(wù)有所幫助,感謝~