참고:

사용자정의 시간범위에 대해 OCI 감사 로그를 CSV 형식으로 익스포트합니다.

소개

OCI 감사 로그는 Oracle Cloud Infrastructure Audit 서비스에서 발행하는 이벤트와 관련이 있습니다. 이러한 로그는 OCI 콘솔 로깅 감사 페이지에서 사용하거나 검색 페이지에서 나머지 로그와 함께 검색할 수 있습니다. Oracle Cloud 콘솔에서 최대 14일의 사용자정의 시간범위에 대해 JSON 형식으로 OCI(Oracle Cloud Infrastructure) 감사 로그를 익스포트할 수 있습니다.

이 사용지침서에서는 14일이 넘는 기간 동안 CSV 형식으로 감사 로그를 익스포트하기 위한 커스터마이징 스크립트를 배포하는 방법을 알아봅니다.

참고: 감사 로그의 최대 보존 기간은 365일입니다.

목표

사용자정의 시간범위(365일 미만)에 대해 OCI 감사 로그를 CSV 형식으로 익스포트하려면 사용자정의 Python 스크립트를 배치하십시오.

필요 조건

작업 1: 사용자 정의 Python 스크립트 배포

  1. 명령을 사용하여 VM에 Python이 설치되었는지 확인합니다.

    python3 –-version
    
  2. 명령을 사용하여 Pandas 라이브러리를 설치합니다.

    pip3 install pandas
    
  3. 새 디렉토리를 생성하고 스크립트를 배치하기 위한 디렉토리로 변경합니다.

    mkdir <directory-name>
    cd <directory-name>
    
  4. 이름이 main.py인 파일을 만들고 편집기를 사용하여 파일을 편집합니다. 여기서 vim 편집기가 사용되었습니다.

    touch main.py
    vim main.py
    
  5. main.py 파일에 아래와 같이 스크립트의 내용을 복사하여 붙여넣고 :x를 입력하고 Enter를 눌러 파일 내용을 저장합니다.

    import pandas as pd
    import csv
    import os
    import datetime
    from datetime import timedelta,date
    import subprocess
    import json
    import sys
    import getopt
    
    def myfunc(argv):
    
        START_DATE = ""
        END_DATE = ""
        COMPARTMENT_ID = ""
        arg_help = "\nUsage:\n\npython3 main.py -s <log_start_date in YYYY-MM-DD Format> -e <log_end_date in YYYY-MM-DD Format> -c <Compartment_ID>\n".format(argv[0])
        try:
            opts, args = getopt.getopt(argv[1:],"hs:e:c:")
        except:
            print("\nenter valid argument values. Try -h option with script to know the usage.\n")
            sys.exit(2)
    
        for opt, arg in opts:
            if opt in ("-h"):
                print(arg_help)  # print the help message
                sys.exit(2)
            elif opt in ("-s"):
                START_DATE = arg
            elif opt in ("-e"):
                END_DATE = arg
            elif opt in ("-c"):
                COMPARTMENT_ID = arg
    
        INC = -1
        year1, month1, day1 = map(int, START_DATE.split('-'))
        DATE1 = datetime.date(year1, month1, day1)
        year2, month2, day2 = map(int, END_DATE.split('-'))
        DATE2 = datetime.date(year2, month2, day2)
        NUM_DAYS = DATE2 - DATE1
        NUM_DAYS = NUM_DAYS.days
    
    # Function for converting JSON to .CSV format
    
        def convert_csv():
    
            with open('out.json', 'r') as file:
                data = json.load(file)
            datetimez = []
            compartmentID = []
            compartmentName = []
            message = []
            tenantId = []
            userAgent = []
            path = []
            ingestedtime = []
            type = []
            id = []
            for ele in data['data']['results']:
                datetimez.append(ele['data']['datetime'])
                compartmentID.append(ele['data']['logContent']['data']['compartmentId'])
                compartmentName.append(ele['data']['logContent']['data']['compartmentName'])
                message.append(ele['data']['logContent']['data']['message'])
                tenantId.append(ele['data']['logContent']['data']['identity']['tenantId'])
                userAgent.append(ele['data']['logContent']['data']['identity']['userAgent'])
                path.append(ele['data']['logContent']['data']['request']['path'])
                ingestedtime.append(ele['data']['logContent']['oracle']['ingestedtime'])
                type.append(ele['data']['logContent']['type'])
                id.append(ele['data']['logContent']['id'])
            finaldate = []
            for ts in datetimez:
                finaldate.append(datetime.datetime.fromtimestamp(int(ts) / 1000).strftime('%Y-%m-%d %H:%M:%S'))
    
            output = zip(finaldate, compartmentID, compartmentName, message, tenantId, userAgent, path, ingestedtime, type, id)
            output = list(output)
            df = pd.DataFrame(output)
            df.to_csv('/tmp/out.csv', header=False , mode='a',index=False)
            return None
    
    # Check and validate the .CSV file in the /tmp directory
    
        os.system("touch /tmp/out.csv" )
        os.remove("/tmp/out.csv")
        header=['Date-Time', 'CompartmentID', 'CompartmentName', 'Message', 'TenantId', 'UserAgent', 'Path', 'Ingested-Time', 'Type', 'ID']
        data = []
        with open('/tmp/out.csv', 'a') as f:
            writer = csv.writer(f)
            writer.writerow(header)
            writer.writerows(data)
    
    # Block for saving Audit Logs in JSON format to out.json file    
    
        for i in range(INC, NUM_DAYS):
            print("\ncollecting logs for", DATE1)
            p = subprocess.Popen(''' oci logging-search search-logs --search-query 'search "''' + str(COMPARTMENT_ID) + '''/_Audit" | sort by datetime desc' --time-start ''' + str(DATE1) + '''"T00:00:00Z" --time-end ''' + str(DATE1) + '''"T23:59:00Z" > out.json ''', shell=True, stdout=subprocess.PIPE)
            (output, err) = p.communicate()
            convert_csv()
            PAG = subprocess.check_output(''' oci logging-search search-logs --search-query 'search "''' + str(COMPARTMENT_ID) + '''/_Audit" | sort by datetime desc' --time-start ''' + str(DATE1) + '''"T00:00:00Z" --time-end ''' + str(DATE1) + '''"T23:59:00Z" | grep "opc-next-page" | awk -F":" '{print $2}' | tr -d '"' | tr -d " " | tail -1 ''', shell=True).strip().decode('ascii')
    
            while (PAG != ""):
                p = subprocess.Popen(''' oci logging-search search-logs --search-query 'search "''' + str(COMPARTMENT_ID) + '''/_Audit" | sort by datetime desc' --time-start ''' + str(DATE1) + '''"T00:00:00Z" --time-end ''' + str(DATE1) + '''"T23:59:00Z" --page ''' + str(PAG) + '''  > out.json ''', shell=True, stdout=subprocess.PIPE)
                (output, err) = p.communicate()
                convert_csv()
                PAG = subprocess.check_output(''' oci logging-search search-logs --search-query 'search "''' + str(COMPARTMENT_ID) + '''/_Audit" | sort by datetime desc' --time-start ''' + str(DATE1) + '''"T00:00:00Z" --time-end ''' + str(DATE1) + '''"T23:59:00Z" --page ''' + str(PAG) + ''' | grep "opc-next-page" | awk -F":" '{print $2}' | tr -d '"' | tr -d " " | tail -1 ''', shell=True).strip().decode('ascii')
            print("successfully collected logs for", DATE1)
            DATE1 += timedelta(days=1)
            i = i + 1
    
        print("\nThe .csv file is saved in location /tmp/out.csv")
    
    if __name__ == "__main__":
        myfunc(sys.argv)
    
    

작업 2: 사용자 정의 Python 스크립트 실행

  1. 명령을 사용하여 main.py 파일에 실행 권한을 제공합니다.

    chmod +x main.py
    
  2. 로그 시작 날짜, 로그 종료 날짜 및 compartment-id 매개변수를 사용하여 스크립트를 실행해야 합니다. 스크립트의 정확한 사용을 확인하려면 아래와 같이 '-h' 옵션을 사용하여 스크립트를 실행하십시오.

    python3 main.py -h
    

    그러면 스크립트의 올바른 구문이 표시됩니다.

    스크립트 도움말

  3. 스크립트를 실행한 후 스크립트가 실행 중인 날짜가 화면에 성공 메시지와 함께 표시되고 출력 .csv 파일 위치를 알리는 메시지가 표시됩니다.

    스크립트 출력

:

nohup python3 main.py -s <log_start_date in YYYY-MM-DD Format> -e <log_end_date in YYYY-MM-DD Format> -c ><Compartment_ID> &

CSV 파일이 생성되어 /tmp/out.csv 폴더에 저장됩니다.

작업 3: 감사 로그 수집 일정 잡기(선택 사항)

감사 로그의 월별/주별 수집 일정을 잡으려면 이전 .csv 파일이 다른 파일로 복사되고 새 로그가 out.csv 파일에 저장되도록 cronjobs를 설정하면 됩니다.

  1. 다음 명령을 입력하여 crontab을 편집합니다.

    crontab -e
    
  2. 일정을 잡을 다음 cronjobs를 추가합니다. ** 매개변수를 구획/테넌시의 구획 ID로 바꾸어야 합니다.

    0 1 1 * * export DATE=$(date +'%Y-%m-%d-%T') && cp /tmp/out.csv out-$DATE.csv
    15 1 1 * * export DATE1=$(date +'%Y-%m-%d') && export DATE2=$(date -d "$DATE1 -1 month" +%Y-%m-%d) && python3 main.py -s DATE1 -e DATE2 -c <Compartment_ID>
    

    위의 작업은 매월 1일 오전 1시와 오전 1시 15분에 각각 실행됩니다. 사용자 요구사항에 따라 시간을 변경할 수 있습니다.

    참고: 한 달의 30일 또는 31일에 실행되도록 작업을 예약하여 스크립트에서 하루를 놓치지 않거나 오류를 반환할 수 있습니다.

  3. 파일을 저장하고 다음 명령을 사용하여 활성 cronjobs를 검토합니다.

    crontab -l
    

승인

추가 학습 자원

docs.oracle.com/learn에서 다른 실습을 탐색하거나 Oracle Learning YouTube 채널에서 더 많은 무료 학습 콘텐츠에 액세스하십시오. 또한 Oracle Learning Explorer가 되려면 education.oracle.com/learning-explorer을 방문하십시오.

제품 설명서는 Oracle Help Center를 참조하십시오.