투케이2K

496. (javaScript) 자바스크립트 AWS CloudWatch 특정 로그 스트림에서 로그 이벤트 (Log Events) 를 조회 수행 - GetLogEvents 본문

JavaScript

496. (javaScript) 자바스크립트 AWS CloudWatch 특정 로그 스트림에서 로그 이벤트 (Log Events) 를 조회 수행 - GetLogEvents

투케이2K 2026. 2. 27. 19:28
728x90
반응형

[개발 환경 설정]

개발 툴 : Edit++

개발 언어 : JavaScript

 

[소스 코드]

-----------------------------------------------------------------------------------------
[사전 설명 및 설정 사항]
-----------------------------------------------------------------------------------------

- 개발 환경 : Web


- 개발 기술 : JavaScript (자바스크립트) / AWS / CloudWatch / GetLogEvents


- 사전) AWS CloudWatch 간단 설명 : 

  >> Aws CloudWatch 는 Amazon Web Services (AWS) 리소스 및 AWS 에서 실행되는 애플리케이션을 실시간으로 모니터링 할 수 있는 서비스입니다

  >> Aws CloudWatch 를 사용하면 시스템 전체의 리소스 사용률, 애플리케이션 성능, 운영 상태를 파악할 수 있습니다

  >> Aws CloudWatch 와 함께 사용할 수 있는 서비스 : 

    - Amazon Simple Notification Service (Amazon SNS) : CloudWatch 와 함께 Amazon SNS를 사용하여 구독 중인 엔드포인트 또는 클라이언트에 메시지를 전달 또는 전송하는 것을 조정하고 관리합니다

    - Amazon EC2 Auto Scaling : Amazon EC2 Auto Scaling 과 함께 CloudWatch 경보를 사용하여 사용자 정의 정책, 상태 확인, 일정에 따라 Amazon EC2 인스턴스를 자동으로 시작하거나 종료할 수 있습니다

    - AWS CloudTrail : AWS CloudTrail 을 사용해 AWS Management Console, AWS CLI 및 기타 서비스에서 수행한 호출을 포함하여 계정의 Amazon CloudWatch API에 대한 호출을 모니터링할 수 있습니다    

    - AWS Identity and Access Management (IAM) : IAM 을 사용하여 AWS 리소스를 사용할 수 있는 사용자를 제어(인증)하고 해당 사용자가 사용할 수 있는 리소스 및 사용 방법을 제어(권한 부여)할 수 있습니다

-----------------------------------------------------------------------------------------





-----------------------------------------------------------------------------------------
[소스 코드]
-----------------------------------------------------------------------------------------

<!DOCTYPE HTML>
<html lang="ko">
<head>
    <title>javaScriptTest</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">


    <!-- 반응형 구조 만들기 -->
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">


    <!-- 내부 CSS 스타일 지정 -->
    <style>

        html, body {
            width: 100%;
            height: 100%;
            margin : 0 auto;
            padding : 0;
            border : none;
            background-color: #666;
        }

    </style>





    <!-- [CDN 주소 설정] -->
    <script src="https://code.jquery.com/jquery-latest.min.js"></script>
    <script src="https://sdk.amazonaws.com/js/aws-sdk-2.1416.0.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/dayjs/1.10.7/dayjs.min.js"></script>






    <!-- [자바스크립트 코드 지정] -->
    <script>

        // --------------------------------------------------------------------------------------------------------------

        // [AWS 인증 변수 선언]        
        const accessKey = 'AK..A6';
        const secretKey = 'mP..5J';
        const region = 'ap-northeast-2';


        // [필요 변수 선언]
        var continueSelect = null;
        var innerFunction = null;
        var sortFlag = true; // 오래된 로그부터 보려면 true, 최신부터 보려면 false
        const selectAllList = [];

        const logGroupName = '/aws/lambda/device-queue-manager';
        const logStreamName = '2026/02/19/[$LATEST]9e5eafa3513e47b1940526aef9d8c34a';

        // --------------------------------------------------------------------------------------------------------------

        // [html 최초 로드 및 이벤트 상시 대기 실시]
        window.onload = async function() {
          console.log("");
          console.log("=========================================");
          console.log("[window onload] : [start]");
          console.log("=========================================");
          console.log("");

          try {

            // -----------------------------------------
            // [초기 변수 초기화]
            // -----------------------------------------
            continueSelect = null;
            innerFunction = null;
            selectAllList.length = 0;


            // -----------------------------------------
            // [AWS.config 지정]
            // -----------------------------------------       
            AWS.config.update({
              region: region,          
              accessKeyId: accessKey,
              secretAccessKey: secretKey
            });


            // -----------------------------------------
            // [AWS 객체 생성]
            // -----------------------------------------
            const aws = new AWS.CloudWatchLogs();


            // -----------------------------------------
            // [내부 함수 생성]
            // -----------------------------------------
            innerFunction = async function() {

              try {
                
                while (true) { // 반복 조회 수행

                  // -----------------------------------------
                  // [요청 파라미터 생성]
                  // -----------------------------------------
                  var param = null;

                  if (continueSelect != null && continueSelect != undefined && continueSelect != ''){
                    param = {                      
                      logGroupName: logGroupName, // 로그 그룹 명칭
                      logStreamName: logStreamName, // 로그 그룹 내에 포함 된 스트림 명칭
                      startFromHead: sortFlag, // 오래된 로그부터 보려면 true, 최신부터 보려면 false
                      limit: 5000, // 반환되는 로그 이벤트의 최대 개수 (최소값 1, 최대값 10000)
                      nextToken: continueSelect // ✅ 반복 조회 요청
                    };
                  }
                  else {
                    param = {
                      logGroupName: logGroupName, // 로그 그룹 명칭
                      logStreamName: logStreamName, // 로그 그룹 내에 포함 된 스트림 명칭
                      startFromHead: sortFlag, // 오래된 로그부터 보려면 true, 최신부터 보려면 false
                      limit: 5000 // 반환되는 로그 이벤트의 최대 개수 (최소값 1, 최대값 10000)
                    };
                  }


                  // -----------------------------------------
                  // Aws CloudWatch Logs 로그 이벤트 조회 수행
                  // -----------------------------------------
                  // AWS 참고 사이트 : https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_GetLogEvents.html
                  // -----------------------------------------       
                  const [err, res] = await aws.getLogEvents(param).promise()
                    .then(data => [null, data])
                    .catch(error => [error, null]);

                  if (err) {
                    console.error("[aws result] : [Error] : ", err);

                    // ---------------------------------------------
                    // ❌ [주요 에러 정리]
                    // ---------------------------------------------
                    // InvalidParameterException : 매개변수가 잘못 지정되었습니다. : HTTP 상태 코드: 400
                    // ---------------------------------------------
                    // ResourceNotFoundException : 지정된 리소스가 존재하지 않습니다. : HTTP 상태 코드: 400
                    // ---------------------------------------------
                    // ServiceUnavailableException : 해당 서비스에서 요청을 완료할 수 없습니다. : HTTP 상태 코드: 500
                    // ---------------------------------------------


                    // ---------------------------------------------
                    // [반복 조회 종료 위한 값 초기화]
                    // ---------------------------------------------
                    continueSelect = null;

                  } else {
                    console.log("[aws result] : [Success] : ", JSON.stringify(res));

                    // ---------------------------------------------
                    // ✅ [로그 출력 예시 첨부]
                    // ---------------------------------------------
                    /*                                         
                    {
                      "events": [
                        {
                          "timestamp": 1739993225000,
                          "message": "2026-02-20T07:27:05.000Z\tab12cd34-x9ff-4e11-af11-6a0edd12efcc\tINFO\tProcessing completed for user test01\n",
                          "ingestionTime": 1739993226123
                        },
                        {
                          "timestamp": 1739993227345,
                          "message": "END RequestId: ab12cd34-x9ff-4e11-af11-6a0edd12efcc\n",
                          "ingestionTime": 1739993228456
                        }
                      ],
                      "nextForwardToken": "f/9038575649823746598237",
                      "nextBackwardToken": "b/9038575649823746598237"
                    }
                    */ 
                    // ---------------------------------------------


                    // ---------------------------------------------
                    // [배열에 리스트 정보 추가]
                    // ---------------------------------------------

                    const resList = res.events;

                    if (resList !== null && resList !== undefined && Array.isArray(resList) && resList.length > 0){                      

                      const parseList = [];

                      for (var i=0; i<resList.length; i++){
                        try {
                          const item = resList[i];

                          var formatJson = item; 

                          if (item.hasOwnProperty("timestamp")){ // 실제 로그 이벤트가 가장 최근 언제 발생했는지 알고 싶다
                            
                            var timeStamp = String(item.timestamp); // 타임스탬프
                            var date = dayjs(Number(timeStamp));
                            formatJson.formatDate = date.format("YYYY-MM-DD HH:mm:ss.SSS");
                          }

                          parseList.push(formatJson);
                        }
                        catch (err){
                          console.error("timestamp parsing exception : ", err);
                        }                        
                      }

                      if (parseList.length > 0){
                        selectAllList.push(...parseList); // ✅ Array Add List
                      }
                      else {
                        selectAllList.push(...resList); // ✅ Array Add List
                      }

                      const result = [...new Set(selectAllList)]; // 중복 제거
                      selectAllList.length = 0; // 초기화

                      selectAllList.push(...result);
                    }
                    

                    // ---------------------------------------------
                    // [반복 조회에 사용 될 정보가 있는지 확인]
                    // ---------------------------------------------
                    const resNext = res.nextForwardToken; // 순방향에서 다음 항목 세트 조회에 대한 토큰입니다.
                    if (resNext !== null && resNext !== undefined && resNext !== ''){
                      
                      if (continueSelect !== resNext){ // ✅ 토큰이 다른 경우만 저장 >> 이전 토큰과 이번 토큰이 같으면 '새 로그 없음' 이므로 잠깐 대기 후 재시도합니다.
                        console.warn('nextForwardToken >> Save');

                        continueSelect = resNext; // ✅ Set
                      }
                      else {
                        console.error('nextForwardToken >> Delete');

                        continueSelect = null; // Clear 
                      }
                      
                    }
                    else {
                      console.error('nextForwardToken >> null');

                      continueSelect = null; // Clear 
                    }

                  }


                  // ---------------------------------------------
                  // [반복 조회에 사용 될 정보가 있는지 확인 후 무한 루프 탈출 수행]
                  // ---------------------------------------------
                  if (continueSelect == null || continueSelect == undefined || continueSelect == ''){
                    console.error("[innerFunction] : [continueSelect] : Is Null >> Stop While True");
                    break;
                  }
                  else {
                    console.warn("[innerFunction] : [continueSelect] : Exists >> Go To While True");
                  }

                }

                
                // ---------------------------------------------
                // [배열 데이터 정렬 수행]
                // ---------------------------------------------
                if (sortFlag == false){
                  const newestFirst = [...(selectAllList || [])].reverse();

                  selectAllList.length = 0; // 초기화

                  selectAllList.push(...newestFirst);
                } 


                console.log("");
                console.log("=========================================");
                console.log("[innerFunction] : Result");
                console.log("---------------------------------------");
                console.log("Length : ", selectAllList.length);
                console.log("---------------------------------------");
                console.log(JSON.stringify(selectAllList));
                console.log("=========================================");
                console.log("");

              }
              catch(exception){
                console.error("[innerFunction] : [Exception] : ", exception);

                // ---------------------------------------------
                // [Body 표시 JSON]
                // ---------------------------------------------
                var errJson = {
                  response: "innerFunction exception",
                  data: exception.message
                }
                // ---------------------------------------------


                // ---------------------------------------------
                // [에러 출력]
                // ---------------------------------------------
                document.write(JSON.stringify(errJson));
                // ---------------------------------------------

              }

            };



            // -----------------------------------------
            // [내부 클로저 함수 호출]
            // -----------------------------------------
            await innerFunction();


            // ---------------------------------------------
            // [Body 표시 JSON]
            // ---------------------------------------------
            var resJson = {
              response: "result",
              data: selectAllList
            }
            // ---------------------------------------------


            // ---------------------------------------------
            // [로그 출력]
            // ---------------------------------------------
            document.write(JSON.stringify(resJson));
            // ---------------------------------------------


          }
          catch (exception) {
            console.error("");
            console.error("=========================================");
            console.error("[window onload] : [Exception] : 예외 상황 발생");
            console.error("-----------------------------------------");
            console.error(exception);
            console.error("=========================================");
            console.error("");

            // ---------------------------------------------
            // [Body 표시 JSON]
            // ---------------------------------------------
            var errJson = {
              response: "try catch exception",
              data: exception.message
            }
            // ---------------------------------------------


            // ---------------------------------------------
            // [에러 출력]
            // ---------------------------------------------
            document.write(JSON.stringify(errJson));
            // ---------------------------------------------

          }

        };

        // --------------------------------------------------------------------------------------------------------------

    </script>


</head>


<body>

</body>

</html>

-----------------------------------------------------------------------------------------





-----------------------------------------------------------------------------------------
[참고 사이트]
-----------------------------------------------------------------------------------------

[Amazon CloudWatch] Aws CloudWatch 클라우드 와치 개념 및 설정 정리 - Aws 애플리케이션 실시간으로 모니터링 서비스

https://kkh0977.tistory.com/7920

https://blog.naver.com/kkh0977/223834321984?trackingCode=blog_bloghome_searchlist


[Amazon 모니터링 및 로깅 서비스] AWS CloudWatch 와 CloudTrail 차이점 정리

https://kkh0977.tistory.com/8143

https://blog.naver.com/kkh0977/223934869835?trackingCode=blog_bloghome_searchlist


[Amazon CloudWatch] DescribeLogGroups AWS CloudWatch Logs 로그 그룹 목록 조회 API 설명 정리

https://kkh0977.tistory.com/8640

https://blog.naver.com/kkh0977/224188525167

-----------------------------------------------------------------------------------------
 
728x90
반응형
Comments