最近在工作中需要对AWS上的部分资源进行查询和交叉分析,虽然场景都比较简单,但是这种半机械的工作当然还是交给Python来搞比较合适。AWS为Python提供的SDK库叫做boto3,所以我们建立一个Python项目,Interpreter选择的是venv解析,再将boto3安装到项目中,下面就可以开始愉快地写代码了。这个过程中有一些坑,记录在这里,以便后续查阅。

Query AWS CloudWatch

根据一定的搜索条件去CloudWatch中查找相关的log记录。

import boto3

def query_cloudwatch_with_condition(log_group, query, start_time, end_time):
"""
Search CloudWatch logs by some conditions.
:param log_group: eg. '/aws/some_log_group'
:param query: eg. f"fields @timestamp, @message \
| sort @timestamp desc \
| filter @message like /(?i)(some_filter)/ \
| filter @message like /Reason:\sError:/ \
| limit 10 \
| display @message"
:param start_time: eg. int((datetime.today() - timedelta(days=5)).timestamp())
:param end_time: eg. int(datetime.now().timestamp())
:return: log message string.
"""
cw_client = boto3.client('logs') start_query_response = cw_client.start_query(
logGroupName=log_group,
startTime=start_time,
endTime=end_time,
queryString=query,
) query_id = start_query_response['queryId']
response = None # NOTE: Must wait for query to complete.
while response is None or response['status'] == 'Running':
print('Waiting for query to complete ...')
time.sleep(1)
response = cw_client.get_query_results(queryId=query_id) issue_detail = ''
# NOTE: In my situation, we only care about the first message because we expect all logs are the same.
for item in response['results'][0]:
if item['field'] == '@message':
issue_detail = item['value']
break return issue_detail

Query DynamoDB

import boto3
from boto3.dynamodb.conditions import Key def query_dynamodb_with_condition(key_conditionn_exp):
"""
Query dynamodb with certain condition_exp (Query not Scan)
:param key_conditionn_exp: eg. Key('id').eq(certain_id) & Key('sk').begins_with('example::')
:return: query results list
"""
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('some-dynamodb-name') response = table.query(KeyConditionExpression=key_conditionn_exp)
items = response['Items'] # filter item if we have further conditions.
for item in items:
pass return items

Scan DynamoDB

对DynamoDB做scan的时候,有个坑是AWS的DynamoDB单次scan是有上限的,所以为了做到full scan,需要在代码里面有一些处理

def scan_dynamodb_with_condition(filter_condition_exp):
"""
Full scan dynamodb with certain condition_exp
:param filter_condition_exp: eg. Attr('sk').eq('my_sk') & Attr('name').begins_with('Jone') & Attr('isDeleted').eq(False)
:return: scan results list
"""
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('some-dynamo-table') response = table.scan(FilterExpression=filter_condition_exp) # Loop to do full scan
results = response['Items']
index = 1
while 'LastEvaluatedKey' in response:
print(f'scanning....{index}')
index += 1
response = table.scan(
ExclusiveStartKey=response['LastEvaluatedKey'],
FilterExpression=filter_condition_exp) results.extend(response['Items'])
print(len(results)) return results

List S3 objects and read contents

读取S3某个路径下的所有objects也有一个坑,就是默认单次get object的上限是1000个,所以如果想做到full list,也需要做特定的处理。

def get_all_s3_objects(s3, **base_kwargs):
"""
Private method to list all files under path
:param s3: s3 client using boto3.client('s3')
:param base_kwargs: scan args
:return: yield file path to caller
"""
continuation_token = None
while True:
list_kwargs = dict(MaxKeys=1000, **base_kwargs)
if continuation_token:
list_kwargs['ContinuationToken'] = continuation_token response = s3.list_objects_v2(**list_kwargs)
yield from response.get('Contents', []) if not response.get('IsTruncated'): # At the end of the list?
break continuation_token = response.get('NextContinuationToken') def main():
bucket_name = 'my-bucket-name'
s3_client = boto3.client('s3')
# using prefix to define search folder
prefix = 'this-is-some-path-without-prefix-and-postfix-slash' file_paths = []
for file in get_all_s3_objects(s3_client, Bucket=bucket_name, Prefix=prefix):
file_paths.append(file['Key']) print(f'length of file_paths: {len(file_paths)}')
with open('./file_paths_results.json', 'w') as f:
f.write(json.dumps(file_paths))
print('finished writing file paths into json file')

Read S3 file contents

在读取S3文件的内容时,我们遇到了文件Body里的内容(来自AWS SQS的message)无法正确的转换为json的问题,因为时间问题,没有太深入地研究,只是简单地做了一些非json语法字串的替换,把内容拿出来了,后面可以再研究一下这种文件内容需要怎么正确加载到json里。

import json
import re
from pprint import pprint import boto3
from dynamodb_json import json_util def read_file_contents(s3client, bucket, path):
"""
Read a file content with it's key (filepath)
:param s3client: eg. boto3.client('s3')
:param bucket: eg. 'some-bucket-name'
:param path: eg. 'some-path-to-my-file-with-postfix-no-slash-prefix'
:return: file contents in json format
"""
file_obj = s3client.get_object(
Bucket=bucket,
Key=path) # open the file object and read it into the variable filedata.
file_data = file_obj['Body'].read() # TODO: we did some ugly string replace here.. will fix this later
print_str = json_util.loads(file_data).replace('\\', '').replace('""', '"').replace('"Body":"', '"Body":').replace(
'}}}"}', '}}}}').replace('= "', '- ').replace('" Or', ' -').replace('" And', ' -') json_obj = json_util.loads(print_str) # NOTE: we use regex to match what we want.
# match = re.findall('someKey":{"S":"(.*?)"', print_str)
# if match:
# pprint(f'find key: {match[0]}')
# return match[0]
# else:
# print(f'no key found!')
# return None return json_obj

本文作为此次生产环境数据问题Investigate的解决过程,记录在这里,数据已经经过脱敏,请结合自己的实际环境进行配置。

Boto3访问AWS资源操作总结(1)的更多相关文章

  1. [原创]java WEB学习笔记55:Struts2学习之路---详解struts2 中 Action,如何访问web 资源,解耦方式(使用 ActionContext,实现 XxxAware 接口),耦合方式(通过ServletActionContext,通过实现 ServletRequestAware, ServletContextAware 等接口的方式)

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  2. Struts2在Action中访问WEB资源

    什么是WEB资源? 这里所说的WEB资源是指:HttpServletRequest, HttpSession, ServletContext 等原生的 Servlet API. 为什么需要访问WEB资 ...

  3. 在centos7中限制kvm虚拟机可访问的资源

    最近通过艰苦卓绝的度娘(我很想用谷歌,可是,你懂的),终于搞明白如何在centos7中限制kvm虚拟机可访问的资源了.度娘给出的结果中,大部分都说的很对,然而,却很难照着做,主要原因有两点:1.网上的 ...

  4. Struts2 之 Action 类访问 WEB 资源

    接着上次博客的内容我继续分享我所学到的知识,和自己在学习过程中所遇到问题以及解决方案.当然,如果读者发现任何问题均可以在下方评论告知我,先谢! 在 Action 中访问 WEB 资源 web 资源 所 ...

  5. SpringMVC拦截器实现:当用户访问网站资源时,监听session是否过期

    SpringMVC拦截器实现:当用户访问网站资源时,监听session是否过期 一.拦截器配置 <mvc:interceptors> <mvc:interceptor> < ...

  6. hystrix完成对redis访问的资源隔离

    相对来说,考虑的比较完善的一套方案,分为事前,事中,事后三个层次去思考怎么来应对缓存雪崩的场景 1.事前解决方案 发生缓存雪崩之前,事情之前,怎么去避免redis彻底挂掉 redis本身的高可用性,复 ...

  7. 零基础学习java------38---------spring中关于通知类型的补充,springmvc,springmvc入门程序,访问保护资源,参数的绑定(简单数据类型,POJO,包装类),返回数据类型,三大组件,注解

    一. 通知类型 spring aop通知(advice)分成五类: (1)前置通知[Before advice]:在连接点前面执行,前置通知不会影响连接点的执行,除非此处抛出异常. (2)正常返回通知 ...

  8. java在访问https资源时,忽略证书信任问题 (转)

    java程序在访问https资源时,出现报错sun.security.validator.ValidatorException: PKIX path building failed: sun.secu ...

  9. spring访问静态资源出错,No mapping found for HTTP request with URI xxx/resources/js/jquery.min.js...

    问题:spring访问静态资源出错,No mapping found for HTTP request with URI xxx/resources/js/jquery.min.js... web.x ...

随机推荐

  1. [loj3156]回家路线

    令$dp[i]$表示经过第$i$条边后的最小烦躁值,有$且dp[i]=\min_{y_{j}=x_{i}且q_{j}\le p_{i}}dp[j]+f(p_{i}-q_{j})$,其中$f(x)=Ax ...

  2. [loj3304]作业题

    (以下假设$T=(V,\{e_{1},e_{2},...,e_{n-1} \})$是一棵树) 根据莫比乌斯反演,有$\gcd(w_{1},w_{2},...,w_{e_{n-1}})=\sum_{d| ...

  3. html+css第四篇

    浮动 float浮动: 1.块在一排显示 2.内联支持宽高 3.默认内容撑开宽度 4.脱离文档流 5.提升层级半层 float:left | right | none | inherit; 文档流是文 ...

  4. .Net Core中使用ElasticSearch(二)

    .Net的ElasticSearch 有两个版本,Elasticsearch.Net(低级) 和 NEST(高级),推荐使用 NEST,低级版本的更灵活,水太深 把握不住.有个需要注意,使用的版本号必 ...

  5. 洛谷 P7516 - [省选联考 2021 A/B 卷] 图函数(Floyd)

    洛谷题面传送门 一道需要发现一些简单的性质的中档题(不过可能这道题放在省选 D1T3 中偏简单了?) u1s1 现在已经是 \(1\text{s}\)​ \(10^9\)​ 的时代了吗?落伍了落伍了/ ...

  6. Atcoder Grand Contest 038 E - Gachapon(Min-Max 容斥+背包)

    Atcoder 题面传送门 & 洛谷题面传送门 我竟然能独立做出 Ag 的 AGC E,incredible!更新了 Atcoder 做题难度上限( 首先按照套路 Min-Max 容斥,\(a ...

  7. IO流中的字符输入输出流及try...catch处理流处理中的异常

    使用字节流读取中文的问题 import java.io.FileInputStream; import java.io.IOException; /* 使用字节流读取中文文件 1个中文 GBK:占用两 ...

  8. 【每天五分钟大数据-第一期】 伪分布式+Hadoopstreaming

    说在前面 之前一段时间想着把 LeetCode 每个专题完结之后,就开始着手大数据和算法的内容. 想来想去,还是应该穿插着一起做起来. 毕竟,如果只写一类的话,如果遇到其他方面,一定会遗漏一些重要的点 ...

  9. 字节面试问我如何高效设计一个LRU,当场懵

    首发公众号:bigsai 转载请放置作者和原文(本文)链接 前言 大家好,我是bigsai,好久不见,甚是想念! 最近有个小伙伴跟我诉苦,说他没面到LRU,他说他很久前知道有被问过LRU的但是心想自己 ...

  10. angular中路由跳转并传值四种方式

    一.路由传值 步骤1 路由传递参数 注意 一定是要传递 索引值 let key = index 这种情况是在浏览器中可以显示对应的参数 这种的是问号 localhost:8080/news?id=2& ...