CDN記錄了所有域名(包括已刪除域名,如果您開通了企業(yè)項(xiàng)目,則已刪除域名不支持此功能)被網(wǎng)絡(luò)用戶訪問(wèn)的詳細(xì)日志,您可以通過(guò)CDN控制臺(tái)查看和下載最近30天的日志,對(duì)您的業(yè)務(wù)資源被訪問(wèn)情況進(jìn)行詳細(xì)分析。
日志轉(zhuǎn)存儲(chǔ)服務(wù)是華為云CDN配合 函數(shù)工作流 ,將CDN日志存儲(chǔ)到OBS桶,可以幫助您將日志存儲(chǔ)更長(zhǎng)的時(shí)間,便于您基于長(zhǎng)時(shí)間的日志做出自定義的數(shù)據(jù)分析,有助于您更好地了解您CDN的服務(wù)質(zhì)量,以及您的終端客戶的訪問(wèn)詳情,提高您的業(yè)務(wù)決策能力。
本文以Python3.6為例,為您介紹通過(guò)API創(chuàng)建FunctionGraph函數(shù)和Timer觸發(fā)器,實(shí)現(xiàn)定時(shí)將CDN日志轉(zhuǎn)存到OBS。
CDN日志轉(zhuǎn)存到OBS需具備的前提條件
暫時(shí)僅支持日志轉(zhuǎn)存到北京四的OBS桶,請(qǐng)您提前準(zhǔn)備好位于北京四的OBS桶。
詳細(xì)操作步驟如下:
創(chuàng)建委托
登錄華為云控制臺(tái),在左側(cè)導(dǎo)航欄,選擇“管理與監(jiān)管> 統(tǒng)一身份認(rèn)證 服務(wù)”。
在左側(cè)導(dǎo)航欄,選擇“委托”頁(yè)簽,單擊右上方的“+ 創(chuàng)建委托”。
在創(chuàng)建委托頁(yè)面,按照如下參數(shù)設(shè)置委托。
委托名稱:FG_TO_CDN。
委托類型:云服務(wù)。
云服務(wù):函數(shù)工作流FunctionGraph。
持續(xù)時(shí)間:永久。
單擊“下一步”,進(jìn)入為“FG_TO_CDN”委托配置權(quán)限界面。
權(quán)限選擇:OBS OperateAccess 、CDN LogsReadOnlyAccess。
單擊“下一步”,配置作用范圍。
作用范圍:全局服務(wù)。
單擊“確認(rèn)”,完成委托配置。
準(zhǔn)備函數(shù)工作流環(huán)境
登錄華為云控制臺(tái),在左側(cè)導(dǎo)航欄,選擇“計(jì)算>函數(shù)工作流”,region選擇“北京四”。
單擊右上方“創(chuàng)建函數(shù)”,進(jìn)入創(chuàng)建函數(shù)界面。
選擇模板:創(chuàng)建空白函數(shù)。
輸入函數(shù)名稱:cdn_to_obs(可自定義)。
所屬應(yīng)用:選擇默認(rèn)的“default”。
委托名稱:選擇已創(chuàng)建好的委托“FG_TO_CDN” 。
企業(yè)項(xiàng)目:選擇“default”。
運(yùn)行時(shí)語(yǔ)言:選擇“Python 3.6”。
代碼上傳方式:選擇“默認(rèn)代碼”。
單擊“創(chuàng)建函數(shù)”,進(jìn)入代碼編輯界面,將代碼示例的代碼內(nèi)容貼入在線IDE。
說(shuō)明:如果有多個(gè)域名的日志需要轉(zhuǎn)存,您需要分別為每個(gè)域名創(chuàng)建一個(gè)函數(shù)工作流。
單擊“配置”,進(jìn)入函數(shù)配置界面。
執(zhí)行超時(shí)時(shí)間:函數(shù)運(yùn)行的超時(shí)時(shí)間,超時(shí)的函數(shù)將被強(qiáng)行停止,建議設(shè)置為900。
說(shuō)明:如果您發(fā)現(xiàn)轉(zhuǎn)存的日志數(shù)量不對(duì),請(qǐng)向“函數(shù)工作流”服務(wù)提工單,增大執(zhí)行超時(shí)時(shí)間。
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ā)器類型:定時(shí)觸發(fā)器 (TIMER)。
定時(shí)器名稱:自定義的定時(shí)器名稱,例如:Timer-0001。
觸發(fā)規(guī)則:Cron表達(dá)式。
Cron表達(dá)式:0 0 8 * * ?(每天早上8點(diǎn)執(zhí)行一次日志轉(zhuǎn)存儲(chǔ))。
是否開啟:開啟。
單擊“確定”,完成定時(shí)觸發(fā)器設(shè)置。
創(chuàng)建測(cè)試事件。在函數(shù)配置界面,單擊右上角“請(qǐng)選擇測(cè)試事件”下拉框,選擇“配置測(cè)試事件”。
配置測(cè)試事件:創(chuàng)建新的測(cè)試事件。
事件模板:空白模板。
事件名稱:test。
測(cè)試事件:{"message":"CDNLog-OBS"}。
單擊“保存”,完成測(cè)試事件創(chuàng)建。
測(cè)試函數(shù)。在函數(shù)詳情頁(yè)面,單擊右上角“請(qǐng)選擇測(cè)試事件”下拉框,選擇“test”,單擊“測(cè)試”。
查看配置是否成功
登錄華為云控制臺(tái),在左側(cè)導(dǎo)航欄,選擇“存儲(chǔ)> 對(duì)象存儲(chǔ)服務(wù) OBS”。
單擊您存儲(chǔ)日志的桶,在左側(cè)導(dǎo)航欄選擇“對(duì)象”。
訪問(wèn)路徑:文件夾(桶名稱)>文件夾(加速域名)>文件夾(日志日期)>日志內(nèi)容。
說(shuō)明:當(dāng)前代碼示例僅支持轉(zhuǎn)存當(dāng)前時(shí)間前一日的日志,如果您需要轉(zhuǎn)存日志的加速域名前一日沒有日志產(chǎn)生,則OBS桶側(cè)不會(huì)產(chǎn)生相關(guān)文件。
OBS桶將對(duì)轉(zhuǎn)存到桶里的日志收費(fèi),具體收費(fèi)規(guī)則請(qǐng)參考計(jì)費(fèi)說(shuō)明。
停止日志轉(zhuǎn)存服務(wù)
. 登錄華為云控制臺(tái),在左側(cè)導(dǎo)航欄,選擇“計(jì)算>函數(shù)工作流”,region選擇“北京四”。
在左側(cè)導(dǎo)航欄選擇“函數(shù)”>“函數(shù)列表”,選中2中創(chuàng)建的函數(shù)名。
在函數(shù)詳情頁(yè)選擇“觸發(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)容對(duì)你的業(yè)務(wù)有所幫助,感謝~