자동 검출 노드에 대한 얕은 탐색.js 응용 프로그램 및 탄력성 APM

나는 아직 Elastic을 위해 일하지 않았다😄), 하지만 나는 그들 제품의 충실한 팬이다.사실:

Elastic APM in particular is one of my favourite pieces of software.

— jukai (樹海) (@theshalvah)


저는 Elastic APM 에이전트를 좋아합니다. 특히 Node.js의 특징 중 하나는 설치가 매우 간단하다는 것입니다.당신이 해야 할 일은:
require('elastic-apm-node').start();
응용 프로그램이 자동으로 감지됩니다.

계기는...


만약 네가 측정 기구에 익숙하지 않다면 그것을 관찰, 측정, 기록으로 볼 수 있다.조작을 위해 기기를 설치할 때, 기기의 시작과 끝 시간을 관찰하고, 그것과 관련된 재미있는 데이터를 측정하고 기록할 것이다.
예를 들어, API 호출을 테스트하면 호출에 얼마나 오래 걸렸는지 측정하려고 할 수 있습니다.URL, 응답 코드, 되돌아오는 HTTP 헤더 등도 기록해야 합니다.우리의 응용 프로그램에서 이러한 조작과 관련된 정보를 기록함으로써 우리는 문제를 디버깅하고 식별하는 데 충분한 유용한 데이터를 가지고 있을 수 있다.
그러면 탄력적인 APM을 사용하여 응용 프로그램에 기기를 추가할 때 무엇을 얻을 수 있습니까?데이터는 다음과 같습니다.
  • 애플리케이션에서 받은 요청 수 및 응답 시간
  • , 그중 대부분의 응용 프로그램의 요청 처리 시간이 여기에 걸렸다(데이터베이스?redis? 외부 API 호출?)
  • 요청 시 실제 데이터베이스 쿼리 및 쿼리당 소요 시간(기타 메타데이터)
  • API 호출 시간 및 기타 메타데이터

  • 아직 많이 남았어요.Elastic의 demo site 을 참조하십시오.

    어떻게 나의 응용을 위해 기기를 설치합니까?


    너에게 응용 기기를 설치하는 가장 직접적인 방법은 수동으로 조작하는 것이다.작업 단위(API 호출, 데이터베이스 조회 또는 작업 단위로 간주되는 모든 작업)를 시작하려면 시작 시간과 유용한 데이터를 기록해야 합니다.완료되면 소요된 시간을 계산하고 기타 데이터를 기록합니다.예를 들어, 애플리케이션에서 뉴스레터를 보낼 경우 다음과 같이 보고 싶습니다.
    // Start the span and record any useful context
    const span = apm.startSpan('newsletter-dispatch');
    span.setLabel('group', group);
    
    // Do the database queries, API calls, etc
    
    // Record any useful data and end the span 
    span.setLabel('newsletters-sent', numberSent);
    // The time taken will be automatically added
    span.end();
    
    많은 검측 라이브러리(예를 들어 Jaegerthe OpenTracing JS client)가 모두 이렇게 일한다.
    수동 방법은 사용자 정의 조작을 기록할 수 있지만, 매번 데이터베이스 조회나 API 호출이 매우 힘들다.이 점에 대해서는 개발자가 라이브러리에 명령을 삽입할 수 있도록 하는 포장기도 있다.예를 들어, Zipkin을 사용하여 PostgreSQL 쿼리를 자동으로 검색하려면 wrap the pg module with Zipkin's library을 사용하여 데이터베이스 쿼리에 사용해야 합니다.

    자동 계기


    더 좋은 선택은 자동 삽입입니다. APM 라이브러리는 사용자가 사용하는 라이브러리를 자동으로 식별하고 그들이 하는 작업을 추적합니다.이것이 바로 신축성 APM의 작업 원리다.벌집사 Beeline, 데이터독 dd-trace, the OpenTelemetry Node.js client도 자동기기를 제공한다.물론 '조작' 은 다른 라이브러리와 상호작용할 때만 발생하는 것이 아니기 때문에, 이 라이브러리들은 수동으로 간격을 추가할 수 있습니다.
    그렇다면 노드에서 어떻게 작동하는지 자동으로 감지된다.js?APM 라이브러리는 언제 새 데이터베이스 질의를 시작했는지 어떻게 알 수 있습니까?그것은 노드로 귀결될 수 있다.js의 모듈 시스템(CommonJS)은 모듈이 require()d일 때 어떤 일이 일어나는지 보고 변경할 수 있습니다. 자바스크립트의 독특한 대상 스타일과 결합하여 대상의 행동을 쉽게 수정할 수 있습니다.

    내부 깊숙이


    APM 클라이언트에서 start() 함수를 호출하면 일련의 구성이 수행되고 나중에 Instrumentation class에서 종료됩니다.
    13 줄에서 플러그인을 지원하는 모듈 목록을 볼 수 있습니다.각 모듈에 대해 에이전트가 패치를 로드합니다(모듈당 패치가 포함된 the modules folder 참조).그리고 스파이 calls the hook() function.이것이 바로 도서관이 실제로 보수된 곳이다.hook() 함수는 다른 탄성 라이브러리 require-in-the-middle에서 제공한다.다음은 당신이 도서관을 어떻게 사용하는지입니다.
    // Assuming we want te make Node's fs.readFile() function Promise-ified, 
    // we could do this
    const hook = require('require-in-the-middle');
    
    // Hook into the fs module
    hook(['fs'], function (exports, name, basedir) {
      const util = require('util');
      exports.readFile = util.promisify(exports.readFile.bind(exports));
      return exports;
    });
    
    // 😈
    const fileContent = await fs.readFile('file.txt');
    
    // You shouldn't do this, though. Use fs.readFileSync() or fs/promises
    
    내부적으로 라이브러리의 기능(단순화)은 다음과 같습니다.
    function hook (modules, onrequire) {
      const originalRequire = Module.prototype.require;
      Module.prototype.require = function (id) {
        // Call the real `require` and get the exported data
        const exports = originalRequire.apply(this, arguments);
        // Pass the export through the hook and return to the user
        return onrequire(exports, moduleName, basedir));
      }
    }
    
    Module.prototype.require은 사용자가 코드에서 호출한 require 함수이기 때문에 우리는 그것을 우리의 함수로 바꾸었다. 이 함수는 require()을 호출할 때 처리 프로그램을 통해 전달될 것이다.
    물론 the real thing에는 캐시, 해석 모듈 경로와 처리 경쟁 조건이 많다.모듈 시스템에 대한 정보를 더 알고 싶으시면 the Node.js docs이 매우 상세합니다.나는 또 노드 중의 갈고리에 관한 내용을 썼다.js 모듈 시스템.다른 사람 hooking into require의 예다.
    마지막 주요 부분은 각 모듈에 대한 도구를 정의하는 것입니다. 보통 내부 API를 연구하고 덮어쓰는 방법입니다.예를 들면 다음과 같습니다.
  • mysql instrumentation MySQL 풀에 getConnection 메소드를 포장하여 반환된 접속 보고서 질의
  • Redis instrumentation RedisClient.prototype.internal_send_command 방법은 모든 새 클라이언트가 명령을 보내기 전에 자동으로 spans를 시작하도록 포장하였다.
  • APM 라이브러리는 shimmer 모듈을 사용하여 포장됩니다.
    shimmer.wrap(object, method, function (original) {
      return myInstrumentedMethod;
    });
    
    이것은 object.method = myNewMethod을 실행하는 것과 같지만, Shimmer는 대량의 테두리 상황과 가능한 오류를 처리하고 쉽게 반전시킬 수 있습니다.
    됐다.우리는 이미 많은 내용을 건너뛰었지만, 이것들은 Elastic APM (그리고 Node.js의 다른 자동 검출 라이브러리) 이 어떻게 작동하는지의 기초이다.만약 당신이 더 많은 것을 알고 싶다면, 원본 코드에는 아직도 많은 내용이 있다.

    좋은 웹페이지 즐겨찾기