데이터엔지니어 군고구마
  • AWS monitoring - Cloud Watch 기반 S3 size 수집
    2019년 11월 16일 15시 40분 42초에 업로드 된 글입니다.
    작성자: DE 군고구마
    반응형

    글을 읽기에 앞서 해당 코드는 python 및 개발 지식이 없는 제가 직접 만든 코드 입니다. 개발자 분이 보시기에 많이 이상 할 수 있습니다. 최적화가 되어 있지 않으며, 코드를 보기에 불편 할 수 있는 점 양해 부탁 드립니다.

     

    1. 수집 조건

    • 모든 Account 내의 S3 Bukcet 수집

     

    2. 수집 내역

    아래의 컬럼명은 수정이 가능하며, 기호에 맞게 사용 부탁 드립니다. 

    계속해서 수정하다 보니 수집하는 명칭이 이상할 수 있습니다.

    enddate : 수집 일자 

    account :  AWS 계정명

    bucket_name : S3 Bucket

    bucket_region : S3 Bucket의 해당 Region

    bucket_size_bytes_Av : Bucket 사이즈 (AWS에서 기본적으로 제공하는 size단위는 byte 입니다.) 

     

    3. 코드

    변경하여 사용 가능한 부분 또는 설명이 필요한 부분만 설명 합니다.

    나머지는 주석으로 되어 있습니다.

    - import library 

    아래의 pymssql이 있는데, 사용자에 맞게 mysql , postgreSQL 등등 불러서 사용하시면 사용 가능 합니다.

    1
    2
    3
    4
    import boto3
    from datetime import datetime, timedelta
    import datetime
    import pymssql
    cs

     

    - AWS 연결 정보 부분 

    아래의 key_list 부분에서 여러개의 Account를 관리 할 수 있도록 해당 Account 및 access,secret key만 넣으면 전부 수집하도록 해놨습니다. 각각의 정보 구분자는 | 이며 서로 다른 Account를 구분하는 것은 , 콤마 입니다.

    region_list의 경우 원하는 region만 넣으면 가능합니다.

    1
    2
    3
    4
    5
    6
    7
    #AWS information 
    #"," multiple entries available 
    #key_list = ['ACCOUNT|ACCESS KEY|SECRET KEY','ACCOUNT2|ACCESS KEY2|SECRET KEY2','ACCOUNT2|ACCESS KEY2|SECRET KEY2']
    key_list = ['ACCOUNT|ACCESS KEY|SECRET KEY']
    access_key = ''
    secret_key = ''
    region = 'ap-northeast-1'
    cs

     

    - 날짜 부분 

    날짜의 경우 D-3 ~ D-2로 하여 2일 전까지의 수치를 계산하는데요. 제가 만들 당시 (2018년)에는 D-1이 잘 안되고 공백으로 API 값을 리턴 하는 경우가 빈번하였습니다. 그래서 계속 공백으로 들어와서 계산이 어려워서 D-2로 하였습니다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #Import date
    now = datetime.datetime.now()
    today = str(now)
    today = today.split(' ')[0]
    #Startdate
    startdate = str(now + datetime.timedelta(days=-3))
    startdate = startdate.split(' ')[0]
    #enddate
    enddate = str(now + datetime.timedelta(days=-2))
    enddate = enddate.split(' ')[0]
    print(today,startdate,enddate)
    cs

     

    - 공백 처리

    위에서 언급한 공백으로 리턴 하는 경우가 있다고 하였는데요. 혹시 몰라서 if문으로 공백일 경우 또한 처리 하도록 함수에 만들었습니다. 

    1
    2
    3
    4
    5
    6
    7
    8
    9
        if sizev != [] :
            bucket_size_bytes_Av = response['Datapoints'][-1]['Average']/1024/1024/1024 #gigabyte 
            param = (enddate,account,bucket_name,bucket_region,round(bucket_size_bytes_Av,5))
            cur.callproc('sqlserver_insert_proc', param)
            conn.commit()
        else:
            param = (enddate,account,bucket_name,bucket_region,0)
            cur.callproc('sqlserver_insert_proc', param)
            conn.commit()
    cs

     

    - 전체 코드

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    import boto3
    from datetime import datetime, timedelta
    import datetime
    import pymssql
    # -----------------------------------------------------------------------------------------------------------------------------------------------
    #AWS information 
    #"," multiple entries available 
    #key_list = ['ACCOUNT|ACCESS KEY|SECRET KEY','ACCOUNT2|ACCESS KEY2|SECRET KEY2','ACCOUNT2|ACCESS KEY2|SECRET KEY2']
    key_list = ['ACCOUNT|ACCESS KEY|SECRET KEY']
    access_key = ''
    secret_key = ''
    region = 'ap-northeast-1'
    # -----------------------------------------------------------------------------------------------------------------------------------------------
    #Database information
    = pymssql.connect(server='HOST',port= 'PORT', user='USER', password='PASS WORD',database='DATABASE NAME')
    cur = conn.cursor()
    # -----------------------------------------------------------------------------------------------------------------------------------------------
    #Import date
    now = datetime.datetime.now()
    today = str(now)
    today = today.split(' ')[0]
    #Startdate
    startdate = str(now + datetime.timedelta(days=-3))
    startdate = startdate.split(' ')[0]
    #enddate
    enddate = str(now + datetime.timedelta(days=-2))
    enddate = enddate.split(' ')[0]
    print(today,startdate,enddate)
    # -----------------------------------------------------------------------------------------------------------------------------------------------
    def get_bucket_size(bucket_name,bucket_region):
        cloudwatch = boto3.client('cloudwatch',aws_access_key_id=access_key, aws_secret_access_key=secret_key,region_name=bucket_region)
        response = cloudwatch.get_metric_statistics(
            Namespace="AWS/S3",
            MetricName="BucketSizeBytes",
            Dimensions=[
                {
                    "Name""BucketName",
                    "Value": bucket_name
                },
                {
                    "Name""StorageType",
                    "Value""StandardStorage"
                }
            ],
            StartTime=startdate,
            EndTime=enddate,
            Period=86400#(1Hour = 3600) 1 = 1Min
            Statistics=['Average']
        )
        sizev = response['Datapoints']
     
        if sizev != [] :
            bucket_size_bytes_Av = response['Datapoints'][-1]['Average']/1024/1024/1024 #gigabyte 
            param = (enddate,account,bucket_name,bucket_region,round(bucket_size_bytes_Av,5))
            cur.callproc('sqlserver_insert_proc', param)
            conn.commit()
        else:
            param = (enddate,account,bucket_name,bucket_region,0)
            cur.callproc('sqlserver_insert_proc', param)
            conn.commit()
    # -----------------------------------------------------------------------------------------------------------------------------------------------
    for key in key_list:
        account = key.split('|')[0]
        access_key = key.split('|')[1]
        secret_key = key.split('|')[2]
        print((account,access_key,secret_key))
        s3 = boto3.resource('s3',aws_access_key_id=access_key, aws_secret_access_key=secret_key,region_name=region) #connect bucket
        client = boto3.client('s3', aws_access_key_id=access_key, aws_secret_access_key=secret_key) #connect bucket
        # -----------------------------------------------------------------------------------------------------------------------------------------------
        for bucket in s3.buckets.all():
            bucket_region = client.head_bucket(Bucket=bucket.name)['ResponseMetadata']['HTTPHeaders']['x-amz-bucket-region']
            get_bucket_size (bucket.name,bucket_region)
     
    cs
    반응형
    댓글