ساخت پسوند AWS Lambda Telemetry API برای ورود مستقیم به Grafana Loki

در معماری های ترکیبی، توابع بدون سرور با راه حل های کانتینری کار می کنند. وقتی گزارشهای CloudWatch را انتخاب نمیکنید، لاگهای Lambda باید ترجمه شوند. روش قدیمی انجام این کار از طریق فیلترهای اشتراک با استفاده از توابع اضافی Lambda برای تبدیل گزارش است. با Lambda Telemetry API روشی زیباتر، کارآمدتر و مقرون به صرفه تر وجود دارد. من از Grafana Loki به عنوان یک نمونه کار استفاده می کنم و به شما نشان می دهم که چگونه یک پسوند Lambda-Loki Telemetry APi فعال بسازید.
استفاده از راه حل متمرکز Logging در محیط های هیبریدی
به عنوان مثال از Grafana Loki به عنوان راه حل متمرکز ورود به سیستم خود استفاده کنید، جایی که ظرف و توابع لامبدا باید سیاهههای مربوط به آنجا ارسال شود بسیار رایج است.
همانطور که در مستندات Lambda-Promtail توضیح داده شده است، برای خواندن گزارش های Lamba باید از فیلتر اشتراک Logs CloudWatch استفاده کنید. همانطور که قهرمان بدون سرور Yan Cui در این مقاله بیان کرد، Transform
Lambda همزمانی Lambda شما را می خورد و هزینه های اضافی اضافه می کند. میتوانید با استفاده از جریانهای Kinesis اضافی از آن استفاده کنید یا از آن استفاده کنید Lambda Telemetry API به عنوان یک پسوند لامبدا.
که این معماری سبک تر را ممکن می کند:
معرفی Lambda Telemetry API
با Lambda Telemetry API، برنامه های افزودنی Lambda می توانند مستقیماً داده های تله متری را از Lambda دریافت کنند.
برنامه های افزودنی لامبدا
با Lambda Extension API می توانید از لایه Lambda استفاده کنید که به عنوان یک فرآیند مستقل در محیط اجرا نامیده می شود و می تواند ادامه دهد پس از پردازش کامل فراخوانی تابع اجرا شود.
Lambda Telemetry API
Telemetry API رویدادها را از این جریانهای تلهمتری دریافت میکند:
-
سکو تله متری – گزارش ها، متریک ها و ردیابی ها که رویدادها و خطاهای مربوط به چرخه عمر زمان اجرا محیط اجرا، چرخه عمر برنامه افزودنی و فراخوانی عملکرد را توصیف می کنند.
-
تابع گزارشها – گزارشهای سفارشی که کد تابع Lambda ایجاد میکند.
-
افزونه گزارشها – گزارشهای سفارشی که کد برنامه افزودنی Lambda ایجاد میکند.
یک برنامه افزودنی میتواند با عضویت در آن، تمام خروجیهای گزارش را از یک تابع Lambda دریافت کند Function
مناسبت ها. انواع رویداد در راهنمای توسعه دهنده تعریف شده است.
توسط نه با عضویت در رویدادهای پلتفرم، رویدادهایی مانند آن را دریافت نخواهید کرد platform.start
رویداد، که ایجاد می کند START
ورودی های گزارش شما فقط خروجی را از خود تابع Lambda دریافت خواهید کرد. به این ترتیب لاگ ها بهتر قابل تجزیه خواهند بود.
گرافانا لبز لوکی
ابزار Grafana اغلب در محیط کانتینری استفاده می شود. بنابراین من پسوند را برای Grafana Loki، که راه حل ورود به سیستم است، خواهم ساخت.
واقعیت جالب: اولین رویکرد من استفاده از قابل تجزیه بود. اما مشخص شد که تجزیه پذیر در حال حاضر قادر به کار با نقش های IAM نیست.
از رویداد Lambda Telemetry API تا promtail
میتوانید رویدادها را با api promtail یا api جدیدتر Loki وارد Loki کنید. api در مستندات توضیح داده شده است. من استفاده خواهم کرد /api/prom/push
زنگ زدن.
کد پسوند
همانطور که AWS در ایجاد برنامه های افزودنی با استفاده از Telemetry API بیان می کند
که توصیه می شود از یک زبان کامپایل شده مانند Golang یا Rust استفاده کنید. بنابراین، البته، من از GO استفاده می کنم.
چند نمونه برنامه افزودنی github وجود دارد. من با استفاده از go-example-telemetry-api-extension
به عنوان نقطه شروع می توانید کد را در مخزن Lambda-Telemetry-API-Loki من مشاهده کنید.
کی به کی زنگ میزنه
برنامه افزودنی در این مراحل اصلی کار می کند:
1) پسوند را با Extensions API ثبت کنید
2) برای دریافت رویدادها یک شنونده HTTP راه اندازی کنید
3) در هر یک از انواع پلتفرم، عملکرد، برنامه افزودنی مشترک شوید
4) رویدادها را دریافت کنید و آنها را به هدف، در اینجا Loki ارسال کنید
1) ثبت نام کنید
این کار از طریق ثبت نام فراخوانی برنامه افزودنی api.
دیدن extensionApi/client.go
:
`
baseUrl := fmt.Sprintf("http://%s/2020-01-01/extension", os.Getenv("AWS_LAMBDA_RUNTIME_API"))
//...
const action = "/register"
url := e.baseUrl + action
///
httpRes, err := e.httpClient.Do(httpReq)
2) شنونده
ساختار از یک سرور HTTP و یک صف تشکیل شده است. به دلایل عملکرد، رویدادها مستقیماً به لوکی منتقل نمی شوند، بلکه در صف قرار می گیرند DISPATCH_MIN_BATCH_SIZE
متغیر محیطی.
پسوند Lambda محیط خود را از تابع Lambda دریافت می کند، بنابراین شما مقادیر را در Lambda Function API تنظیم می کنید.
type TelemetryApiListener struct {
httpServer *http.Server
// LogEventsQueue is a synchronous queue and is used to put the received log events to be dispatched later
LogEventsQueue *queue.Queue
}
3) مشترک شوید
که در telemetryApi/client.go
کارکرد Subscribe
تماس می گیرد baseUrl
از تله متری افزونه:
baseUrl := fmt.Sprintf("http://%s/2022-07-01/telemetry", os.Getenv("AWS_LAMBDA_RUNTIME_API"))
پارامترهای ممکن در مرجع Lambda Telemetry API توضیح داده شده است.
برای مثال، اگر انتظار دادهای با حجم بالا دارید، باید اندازه دسته و پارامتر بافر تماس مشترک را تنظیم کنید.
اکنون که یک افزونه داریم، باید آن را بسازیم و در توابع Lambda نصب کنیم.
ساخت و نصب لایه تله متری
در مخزن با کمک فایل وظیفه بزرگ لایه های باینری را می سازم:
cd loki_extension
task build
که صدا می زند:
GOOS=linux GOARCH=amd64 go build -o dist/extensions/grafana-loki-extension main.go
که یک باینری اجرایی برای معماری amd64 ایجاد می کند. اگر از معماری بازو استفاده می کنید، باید متغیر GOARCH را تغییر دهید. باینری ایجاد شده فشرده شده و به صورت لایه Lambda منتشر می شود.
برای تنظیم لایه ARN در تابع لامبدا، ARN را ذخیره می کنم.
با افزونه، زمان اجراهای سازگار را تعریف می کنید --compatible-runtimes
برای لایه لامبدا
کل تماس:
ARN=`aws lambda publish-layer-version --layer-name "grafana-loki-extension" --region eu-central-1 --compatible-runtimes nodejs16.x go1.x python3.9 --zip-file "fileb://extension.zip" --query "LayerVersionArn" --output text` && echo $ARN
خروجی:
arn:aws:lambda:eu-central-1:012345679812:layer:grafana-loki-extension:1
اکنون لایه در حساب فعلی AWS نصب شده است. میتوانیم بدون تغییر یک خط از کد تابع، از لایه در توابع لامبدا استفاده کنیم.
راه اندازی تست معماری
راه اندازی دارای سه جزء است:
1) لایه تله متری با پسوند Loki
2) ظروف Grafana Loki و سایر ابزارهای تله متری به عنوان راه اندازی docker-compose
3) تست توابع Lambda برای Telemetry API نوشته شده در TypeScript، Python و Go
1) لایه تله متری
این همان لایه ای است که من نصب کردم. برای تابع لامبدا به ARN ارجاع می دهید:
arn:aws:lambda:eu-central-1:012345679812:layer:grafana-loki-extension:1
.
2) ابزار Grafana
من از تنظیمی از کتاب Cloud-Native Observability with OpenTelemetry استفاده می کنم
این هست نه برای تولید. برای تنظیمات بهتر، مقالات دیگر این مجموعه را ببینید.
راه اندازی شامل:
- کلکسیونر Opentelemetry
- پرومتئوس
- لوکی
- Promtail
- گرافانا
برای یک محیط آزمایشی، کانتینرها را در یک سرور Cloud9 در یک شبکه عمومی راه اندازی می کنیم.
2.1. یک محیط Cloud 9 ایجاد کنید
2.2. قوانینی را به گروه امنیتی نمونه باز شده به IP خود اضافه کنید و api Loki/Promtail را برای آدرسهای IP Lambda مانند:
برای تولید، شما باید یک راهاندازی احراز هویت یا/و Lambda در VPC در یک زیرشبکه خصوصی داشته باشید تا IPهای ثابتی دریافت کنید.
2.3. نصب Docker Compose در Cloud9:
sudo curl -L "https://github.com/docker/compose/releases/download/1.23.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker-compose --version
خروجی:
AWSReservedSSO_AWSAdministratorAccess_b58ba5bc1d953bb1:~/environment $ docker-compose --version
docker-compose version 1.23.1, build b02f1306
2.4. کلون کردن مخزن:
git clone https://github.com/megaproaktiv/Lambda-Telemetry-API-Loki.git
cd Lambda-Telemetry-API-Loki/grafana-container/
2.5. محیط Grafana را راه اندازی کنید:
docker-compose up
خروجی:
Creating network "grafana-container_observability" with the default driver
...
2.6. گرافانا را باز کنید
اکنون ابزارهای Grafana باید در حال اجرا باشند، بنابراین IP عمومی نمونه Cloud9 خود را در پورت باز کنید 3000
.
مثال: http://3.67.195.192:3000/?orgId=1
شما باید چیزی شبیه به:
3) توابع لامبدا
در دایرکتوری lambda_telementry_api
منابع Lambda با CDK تعریف شده اند.
اگر از نسخه لایه دیگری استفاده می کنید، باید url را در آن تطبیق دهید lib/lambda_telementry_api-stack.ts
:
const extensionName = "grafana-loki-extension"
const layerVersion="1"
const loki_ip="3.67.195.192"
const distpatch_min_batch_size = "10"
const lambdatelematryApiLayerArn = "arn:aws:lambda:"+region+":"+account+":layer:"+extensionName+":"+layerVersion
const ltaLayer = lambda.LayerVersion.fromLayerVersionArn(this, "ltalayer", lambdatelematryApiLayerArn)
همچنین IP Loki را از مرحله آخر تنظیم کنید.
مطمئن شوید که داکر را در حال اجرا کرده اید و پشته CDK را با استفاده از:
task deploy
این همه توابع لامبدا را ساخته و آنها را مستقر می کند.
اکنون ما یک راهاندازی ورود سادهتر ایجاد کردهایم:
تنظیمات را تست کنید
توابع Lambda تمام رویدادهای PutObject را از یک سطل S3 می گیرند و کلید شی را در DynamoDB می نویسند.
یک اسکریپت تست در داخل وجود دارد lambda_telementry_api
دایرکتوری که شی را در سطل ایجاد شده قرار می دهد:
/test/traffic.sh
اسکریپت را بعد از تقریباً متوقف کنید. 20 کپی تماس.
خروجی به نظر می رسد:
So 12 Feb 2023 14:42:17 CET
upload: ./readme.md to s3://lambdatelementryapistack-incoming0b397865-hjxvhc2842jy//test-4-0-0-
So 12 Feb 2023 14:42:18 CET
upload: ./readme.md to s3://lambdatelementryapistack-incoming0b397865-hjxvhc2842jy//test-4-0-1-
گزارشهای CloudWatch تابع Lambda اکنون خروجی برنامه افزودنی را نیز نشان میدهند. سطح گزارش روی پرمخاطب تنظیم شده است، بنابراین می توانید بسیاری از رویدادها را ببینید:
رویدادها را از برنامه افزودنی ثبت کنید
time="2023-02-12T13:42:18Z" level=info msg="[main] Starting the Telemetry API extension" pkg=main
time="2023-02-12T13:42:18Z" level=info msg="[main] Registering extension" pkg=main
time="2023-02-12T13:42:18Z" level=info msg="[client:Register] Registering using baseURLhttp://127.0.0.1:9001/2020-01-01/extension" pkg=extensionApi
time="2023-02-12T13:42:18Z" level=info msg="[client:Register] Registration success with extensionId 5b43e095-292c-4d3c-94d0-be9cea43c78d" pkg=extensionApi
time="2023-02-12T13:42:18Z" level=info msg="[main] Registation success with extensionId5b43e095-292c-4d3c-94d0-be9cea43c78d" pkg=main
time="2023-02-12T13:42:18Z" level=info msg="[main] Starting the Telemetry listener" pkg=main
time="2023-02-12T13:42:18Z" level=info msg="[listener:Start] Starting on addresssandbox:4323" pkg=telemetryApi
time="2023-02-12T13:42:18Z" level=info msg="[main] Subscribing to the Telemetry API" pkg=main
time="2023-02-12T13:42:18Z" level=info msg="[client:Subscribe] Subscribing using baseUrl:http://127.0.0.1:9001/2022-07-01/telemetry" pkg=telemetryApi
صف منتظر خاموش شدن یا اگر distpatch_min_batch_size
رسیده است:
time="2023-02-12T13:58:16Z" level=info msg="[listener:http_handler] logEvents received:1 LogEventsQueue length:2" pkg=telemetryApi
time="2023-02-12T14:02:18Z" level=info msg="[listener:http_handler] logEvents received:2 LogEventsQueue length:11" pkg=telemetryApi
time="2023-02-12T14:02:18Z" level=info msg="[dispatcher:Dispatch] Dispatching :11 log events" pkg=telemetryApi
ثبت رویدادها از پلتفرم
INIT_START Runtime Version: python:3.9.v16 Runtime Version ARN: arn:aws:lambda:eu-central-1::runtime:07a48df201798d627f2b950f03bb227aab4a655a1d019c3296406f95937e2525
END RequestId: 1af7f8ab-94e7-4a7a-b3c8-db06eedf874b
REPORT RequestId: 1af7f8ab-94e7-4a7a-b3c8-db06eedf874b Duration: 132.32 ms Billed Duration: 133 ms Memory Size: 1024 MB Max Memory Used: 83 MB Init Duration: 783.94 ms
رویدادها را از تابع ثبت کنید
پایتون لامبدا lambda_telementry_api/lambda/py/app.py
پاسخ DynamoDb را ثبت می کند:
for record in message['Records']:
itemKey = record['s3']['object']['key']
response = putDynamoItem(environment['Table'], itemKey)
print(response)
در گزارش های cloudwatch می بینیم:
{'ConsumedCapacity': {'TableName': 'items', 'CapacityUnits': 1.0}, 'ResponseMetadata': {'RequestId': 'DPKG7GR6V8G0SA2ATEPR2M4UB3VV4KQNSO5AEMVJF66Q9ASUAAJG', 'HTTPStatusCode': 200, 'HTTPHeaders': {'server': 'Server', 'date': 'Sun, 12 Feb 2023 13:42:19 GMT', 'content-type': 'application/x-amz-json-1.0', 'content-length': '62', 'connection': 'keep-alive', 'x-amzn-requestid': 'DPKG7GR6V8G0SA2ATEPR2M4UB3VV4KQNSO5AEMVJF66Q9ASUAAJG', 'x-amz-crc32': '2296128304'}, 'RetryAttempts': 0}}
حالا باید همین اتفاق را در گرافانا ببینیم.
گزارش های تابع را در Grafana Loki / Grafana جستجو کنید
لوکی با برچسب ها کار می کند. برای یافتن توابع Lambda، کلاینت promtail با نام تابع به عنوان برچسب در مقداردهی اولیه می شود. loki/promtail.go
:
function_name = os.Getenv("AWS_LAMBDA_FUNCTION_NAME")
labels := "{source=\""+source_name+"\",function=\""+function_name+"\"}"
lokiIp := os.Getenv("LOKI_IP")
if len(lokiIp) == 0 {
panic("LOKI Ip undefined")
}
conf = promtail.ClientConfig{
PushURL: "http://"+lokiIp+":3100/api/prom/push",
Labels: labels,
BatchWait: 5 * time.Second,
BatchEntriesNumber: 10000,
SendLevel: promtail.INFO,
PrintLevel: promtail.ERROR,
}
همه رویدادهای عملکرد لامبدا با عنوان برچسب گذاری شده اند Source=Lambda
در مرورگر Grafana Loki (2) را با نماد کاوش (1) شروع کنید:
بنابراین پس از ورود اولین رویدادها به لوکی، این برچسب ها را مشاهده می کنید:
برچسب source
نشان می دهد که ما داریم Lambda
وقایع و سه متفاوت function
برچسبها به ما اجازه میدهند هر یک از توابع را پرس و جو کنیم.
وقتی این برچسب ها را پرس و جو می کنید، دریافت می کنید فقط گزارشهای عملکرد، نه گزارشهای پلتفرم یا برنامههای افزودنی مانند CloudWatch:
بنابراین پسوند کار می کند و همه چیز گزارش عملکرد به لوکی ارسال می شوند!
خلاصه
برنامه افزودنی API و برنامه های افزودنی تله متری Lambda امکان اتصال داده های تله متری به اهداف AWS و غیر AWS را فراهم می کند.
اگر برنامه افزودنی راهاندازی و اجرا شود، انعطافپذیری بسیار بیشتری نسبت به CloudWatch به تنهایی دارید. از سوی دیگر، Lambda به شدت با گزارشهای CloudWatch یکپارچه شده است و برای دریافت آن، باید لایههای اضافی را پیکربندی نکنید.
بنابراین برای برنامه استاندارد بدون سرور، پسوندها نباید ضروری باشند. اما برای پروژه های با حجم بالا یا ترکیبی، عملکرد بیشتری را فراهم می کند و در هزینه ها صرفه جویی می کند زیرا به منابع اضافی در قالب Log Function نیاز ندارید.
مزیت اصلی این است که توابع لامبدا ثبت نام همزمانی لامبدا را مصرف نمی کند. همچنین، میتوانید تصمیم بگیرید که کدام رویدادهای گزارش را میخواهید ببینید.
این مقاله مجموعه ای در مورد مشاهده پذیری بدون سرور را به پایان می رساند.
اگر برای پروژه بدون سرور خود نیاز به مشاوره دارید، در تماس با اسپانسر این وبلاگ یعنی tecRacer تردید نکنید.
برای اطلاعات بیشتر در مورد توسعه AWS، من را در برنامه توسعه https://dev.to/megaproaktiv دنبال کنید.
همچنین ببینید