-
Notifications
You must be signed in to change notification settings - Fork 82
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement AccessLog support for Ballerina #1969
base: master
Are you sure you want to change the base?
Implement AccessLog support for Ballerina #1969
Conversation
@@ -144,6 +145,9 @@ public synchronized void addHttpContent(HttpContent httpContent) { | |||
public HttpContent getHttpContent() { | |||
HttpContent httpContent = this.blockingEntityCollector.getHttpContent(); | |||
this.contentObservable.notifyGetListener(httpContent); | |||
if (httpContent != null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
blockingEntityCollector
can contain multiple http contents right? In this case we only consider 1 content and set it to the carbon msg. Is that correct?
@@ -53,6 +59,7 @@ public class ReceivingEntityBody implements SenderState { | |||
private final Http2TargetHandler http2TargetHandler; | |||
private final Http2ClientChannel http2ClientChannel; | |||
private final Http2TargetHandler.Http2RequestWriter http2RequestWriter; | |||
private Long contentLength = 0L; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
im not sure about storing the content length in the state itself. while receiving the entity body, there is a possibility for the state to change right? if it changes, when receiving the response body again, a new ReceivingEntityBody state will be created that doesn't have the previous contentLength value. This is a possibility right? @TharmiganK
This PR has been open for more than 15 days with no activity. This will be closed in 3 days unless the |
cf289ec
to
a8d6a34
Compare
252ce36
to
a8d2f46
Compare
|
e4adba3
to
a115354
Compare
a115354
to
3dfd0e1
Compare
native/src/main/java/io/ballerina/stdlib/http/api/logging/accesslog/HttpAccessLogConfig.java
Show resolved
Hide resolved
native/src/main/java/io/ballerina/stdlib/http/api/logging/accesslog/HttpAccessLogConfig.java
Outdated
Show resolved
Hide resolved
private List<HttpAccessLogMessage> getHttpAccessLogMessages(HttpCarbonMessage request) { | ||
Object outboundAccessLogMessagesObject = request.getProperty(OUTBOUND_ACCESS_LOG_MESSAGES); | ||
if (outboundAccessLogMessagesObject instanceof List<?> rawList) { | ||
for (Object item : rawList) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is there a possibility for the rawList to contain other LogMessage types than HttpAccessLogMessage
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ATM, no only HttpAccessLogMessage
Description
This pull request addresses the proposal detailed in ballerina-platform/ballerina-library#6111. The implementation has been completed, and comprehensive load tests were conducted to evaluate the performance with and without the access log feature enabled.
The load tests were executed for 30 minutes to ensure stability and performance consistency. Different backends and testing tools were utilized for HTTP/1.1 and HTTP/2 passthrough scenarios:
HTTP/1.1 Passthrough Scenarios:
HTTP/2 Passthrough Scenarios:
These configurations were chosen to handle each protocol's specific requirements and challenges effectively. Additionally, we have added the load test results and memory usage metrics for the HTTP/2 passthrough scenarios, providing detailed insights into the performance and resource consumption under heavy load conditions.
Load Test Results:
h1-h1-pass-through scenario (Apache JMeter)
h1-h2-pass-through scenario (Apache JMeter)
h2-h2-pass-through scenario (h2load)
Result
![h2_h2_log_disabled_result](https://private-user-images.githubusercontent.com/33729295/338871342-efda85de-d5cc-4538-b55c-38b4c33a711e.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MTk1MzkwMTQsIm5iZiI6MTcxOTUzODcxNCwicGF0aCI6Ii8zMzcyOTI5NS8zMzg4NzEzNDItZWZkYTg1ZGUtZDVjYy00NTM4LWI1NWMtMzhiNGMzM2E3MTFlLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA2MjglMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwNjI4VDAxMzgzNFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWJlNDI4MDYyMDc4ZTRlMTZiMzM2ZjU3ODkwNWU2YThhNmM0ZjQxZWYwNzMzNmY2NTJlNzhmMWQzYWYzZjVjMGUmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.VySnPxYPEwGzjV7fXvPV-EKOCn4moATX5aoQADDWySk)
Heap
![h2_h2_log_disabled_heap](https://private-user-images.githubusercontent.com/33729295/338871319-03a819ce-294e-4369-9894-7549a77e0859.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MTk1MzkwMTQsIm5iZiI6MTcxOTUzODcxNCwicGF0aCI6Ii8zMzcyOTI5NS8zMzg4NzEzMTktMDNhODE5Y2UtMjk0ZS00MzY5LTk4OTQtNzU0OWE3N2UwODU5LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA2MjglMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwNjI4VDAxMzgzNFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWUyNTBiNTRkMmQxNmYwODI3ZDE0ZjViZjExZTgzMmRiNzRmY2Q0MGJlNmEyMzBkMzgyOWM2Nzk5YTNjNTAwZGUmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.-ZClmyw0by9muGiDdBbhMSh-QRbjQQQBnwvJ5aI-kgA)
CPU
![h2_h2_log_disabled_cpu](https://private-user-images.githubusercontent.com/33729295/338871282-d4e12def-c5f0-4416-91b4-a5c8abb77771.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MTk1MzkwMTQsIm5iZiI6MTcxOTUzODcxNCwicGF0aCI6Ii8zMzcyOTI5NS8zMzg4NzEyODItZDRlMTJkZWYtYzVmMC00NDE2LTkxYjQtYTVjOGFiYjc3NzcxLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA2MjglMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwNjI4VDAxMzgzNFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTA0NzNlYWMzYmQ3OWZlMDUxNjFkYmM2ZmViZjhmMWJhYWY3MWZhNGYyZmZiZDdmYzA3ZGYwMTA1N2Y3N2I1MTcmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.9tUIs_fEzhI3xp0iYZTY9I8btg-uLnUiY3fsewVHLX4)
Result
![h2_h2_log_enabled_result](https://private-user-images.githubusercontent.com/33729295/338873786-9d39602b-4b57-4746-ba6f-94115b99b4fa.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MTk1MzkwMTQsIm5iZiI6MTcxOTUzODcxNCwicGF0aCI6Ii8zMzcyOTI5NS8zMzg4NzM3ODYtOWQzOTYwMmItNGI1Ny00NzQ2LWJhNmYtOTQxMTViOTliNGZhLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA2MjglMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwNjI4VDAxMzgzNFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWI3ODJiZTg5MGU4ZmExZjY0ZjQ2NDU3NzVjYjA5OWZhMDVkN2NiMzVhOTQzZDljZjZmNmJiNTA1MjUyZmI4MjMmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.QGMgW8Pum9LvJAPhW3U4v1kDLtb1-TpPTyTvyo1YkFY)
Heap
![h2_h2_log_enabled_heap](https://private-user-images.githubusercontent.com/33729295/338873021-81451855-88ba-4998-a2db-e2df5c7ade0d.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MTk1MzkwMTQsIm5iZiI6MTcxOTUzODcxNCwicGF0aCI6Ii8zMzcyOTI5NS8zMzg4NzMwMjEtODE0NTE4NTUtODhiYS00OTk4LWEyZGItZTJkZjVjN2FkZTBkLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA2MjglMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwNjI4VDAxMzgzNFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTBiNGM0MjkyMDI1ZWNlN2NlOTE1ZjY3NzBhYTM1ZjU5NmNlNGQ3MmMxMmNiYmEzYTQ2OTg4ZmVhNDZkMWI2ZmImWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.EL_RjwqsTL3RvoE7icUqnvzftDEKlJEH7KX2pU1u7W8)
CPU
![h2_h2_log_enabled_cpu](https://private-user-images.githubusercontent.com/33729295/338873047-545cf307-c53c-4409-9ea8-4f92e9fb919c.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MTk1MzkwMTQsIm5iZiI6MTcxOTUzODcxNCwicGF0aCI6Ii8zMzcyOTI5NS8zMzg4NzMwNDctNTQ1Y2YzMDctYzUzYy00NDA5LTllYTgtNGY5MmU5ZmI5MTljLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA2MjglMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwNjI4VDAxMzgzNFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTdmYjBiNjlhMjc2MzY0YmI4ZTg5YTkxOThhMTAyMWQzM2U2ZGM5ZDYyNWYzNWNkNTEwNWEyYTlhYTFjOWIyZDkmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.UQQy2GP-HLw3ryiZ8Cca3gF5d01M3ZWN_qs2W4sIAVQ)
h2-h1-pass-through scenario (h2load)
Result
![h2_h1_log_disabled_result](https://private-user-images.githubusercontent.com/33729295/338885039-1dc017c5-ec8b-4d12-bec7-ba13f558e2e7.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MTk1MzkwMTQsIm5iZiI6MTcxOTUzODcxNCwicGF0aCI6Ii8zMzcyOTI5NS8zMzg4ODUwMzktMWRjMDE3YzUtZWM4Yi00ZDEyLWJlYzctYmExM2Y1NThlMmU3LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA2MjglMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwNjI4VDAxMzgzNFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTExN2QxOTEwZDkzZjlmZmU1NzVjYzk1NWQ5MjU3MmM1MWEyYjQ0ZmQzNGRhYTU2NTc4ZWFjM2I0ZDgzOGEwOWUmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.e0reNEyxAYp_ZpdsCfkCCSYyBtK_iARpwfnArBpsLlk)
Heap
![h2_h1_log_disabled_heap](https://private-user-images.githubusercontent.com/33729295/338885074-75e74ef1-92d9-43dd-a9cc-f5473d6c48c0.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MTk1MzkwMTQsIm5iZiI6MTcxOTUzODcxNCwicGF0aCI6Ii8zMzcyOTI5NS8zMzg4ODUwNzQtNzVlNzRlZjEtOTJkOS00M2RkLWE5Y2MtZjU0NzNkNmM0OGMwLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA2MjglMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwNjI4VDAxMzgzNFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTgwZGJlN2JhOGYzZWQ5YjIzMTBlZGY5NjljZDY1MjQxMTUzZmQxMzFmMWYyYjg1MDcyMDU2NWE5MjBmMWMwZDUmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.j7pAakaScBbU0T6PVpmt28bTpIj_o4fO2T1Nuu7J3Ss)
CPU
![h2_h1_log_disabled_cpu](https://private-user-images.githubusercontent.com/33729295/338885091-f99e3242-f7da-4fa7-a055-b89fd059153c.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MTk1MzkwMTQsIm5iZiI6MTcxOTUzODcxNCwicGF0aCI6Ii8zMzcyOTI5NS8zMzg4ODUwOTEtZjk5ZTMyNDItZjdkYS00ZmE3LWEwNTUtYjg5ZmQwNTkxNTNjLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA2MjglMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwNjI4VDAxMzgzNFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTAzZDUxZGM1ZjcwZjQ0YjBkOWE1ZTNjNjQwY2E0MjcyODU5NzUyMGMzNGE1ODI5NDMxZWJkMzFkMDY5OTNiODkmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.h_1ubentucediGNwfwkdsImXR8eFrgntxNn9d8_ALeo)
Result
![h2_h1_log_enabled_result](https://private-user-images.githubusercontent.com/33729295/338878072-de6ce2ef-f3b6-4c7e-b3ba-088a87fb072a.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MTk1MzkwMTQsIm5iZiI6MTcxOTUzODcxNCwicGF0aCI6Ii8zMzcyOTI5NS8zMzg4NzgwNzItZGU2Y2UyZWYtZjNiNi00YzdlLWIzYmEtMDg4YTg3ZmIwNzJhLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA2MjglMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwNjI4VDAxMzgzNFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWE5YmU0YWMwNjk3MDdkNmEzZGZjYTZmODU3ZDAzMDkyMzQ4ZWRlMDIzOGY4NWJiMjA1ZmFkYTZjNTZmODhmZWYmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.4eeirSjN8TdV5W9JAbtD9ATQw94_XmmJgCdMZXeDdvg)
Heap
![h2_h1_log_enabled_heap](https://private-user-images.githubusercontent.com/33729295/338878096-89ad0e1b-53df-4744-bfb8-ee3d3368f3b9.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MTk1MzkwMTQsIm5iZiI6MTcxOTUzODcxNCwicGF0aCI6Ii8zMzcyOTI5NS8zMzg4NzgwOTYtODlhZDBlMWItNTNkZi00NzQ0LWJmYjgtZWUzZDMzNjhmM2I5LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA2MjglMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwNjI4VDAxMzgzNFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWI1OGVmOGNlNmEwMmFkNGEwYmI1NWVkYTEzNTllNTMxMjY2NDhkNTIxOGJlYTk0MjU0ZDg4OWIzMDkwNDZlMGMmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.g37nfe4eV2hc-mD961UYIkZFLgU6UEtviCCGwHVR_zY)
CPU
![h2_h1_log_enabled_cpu](https://private-user-images.githubusercontent.com/33729295/338878117-32863591-5eaf-4f8b-a75f-430ed9e6f20a.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MTk1MzkwMTQsIm5iZiI6MTcxOTUzODcxNCwicGF0aCI6Ii8zMzcyOTI5NS8zMzg4NzgxMTctMzI4NjM1OTEtNWVhZi00ZjhiLWE3NWYtNDMwZWQ5ZTZmMjBhLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA2MjglMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwNjI4VDAxMzgzNFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTE1ZWI0NWI0YzNjNmYyZGIwZDRiMTdkNmYxMjNmZGU2OTRmMzllN2QxOWVmYjBhM2QxM2FhZjUzMjE5ZjQzMDMmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.MAHSYC9B5sPjrkVZppi4w_KuMJcHsJQU-t6QhlkdVQM)
Examples
Checklist