왜 니 노드가js 응용 프로그램이 로그 루트를 처리하지 않습니까?

11087 단어 devopsnodejavascript
최초 발표coreycleary.me.이것은 나의 콘텐츠 블로그의 교차 게시물이다.나는 1, 2주에 한 번씩 새로운 내용을 발표하는데, 만약 당신이 나의 글을 우편함으로 직접 보내고 싶다면, 당신은 sign up to my newsletter!나는 또 자주 메모지와 기타 무료 경품을 발송한다.
It is not the responsibility of the application to route logs.

12 Factor says that logs should go to STDOUT. WAT? WHY?

I just configured my whole application code to write logs to custom log files. What's wrong with that?

로그 기록은 때때로 개발자의 블랙박스가 될 수 있다.로그 인프라를 담당하는 전문적인 DevOps 직원이 있거나, 이 분야에 종사하는 것은 이번이 처음일 수도 있습니다.
코드를 작성하느라 바쁠 때, 그것은 아마도 마지막까지 남아서 처리하는 일 중의 하나일 것이다.많은 사람들이 이렇게 했습니다. 이로 인해 로그 기록의'최선의 실천'은 당신이 소홀히 할 수 있는 것처럼 보였습니다. 만약 당신이 처음부터 그것들을 이해했다면...
로그와 응용 프로그램을 분리하는 최선의 실천 뒤에 있는 이유와 실제 로그인해야 할 위치를 알아보겠습니다.본고에서 로그 루트 (제목에서 설명한 바와 같이) 는 로그를 추출하여 응용 프로그램이나 응용 프로그램 프로세스가 아닌 로그 대상으로 보내는 것을 가리킨다.

모범 사례 설명


당신은 이전에 12가지 요소 응용 프로그램을 들어 본 적이 있을 것이다. 이것은 현대적이고 확장 가능한 응용 프로그램을 만드는 규범인'최선의 실천'문서로 여겨진다.
"12 Factor App best practices regarding logs:
A twelve-factor app never concerns itself with routing or storage of its output stream. It should not attempt to write to or manage logfiles. Instead, each running process writes its event stream, unbuffered, to stdout.... In staging or production deploys, each process’ stream will be captured by the execution environment, collated together with all other streams from the app, and routed to one or more final destinations for viewing and long-term archival. These archival destinations are not visible to or configurable by the app, and instead are completely managed by the execution environment.

이것은 해독이 매우 많기 때문에 우리가 그것을 분해합시다.
"A twelve-factor app never concerns itself with routing or storage of its output stream."

응용 프로그램 코드 자체가 로그 루트를 처리하는 것을 원하지 않는 첫 번째 주요 원인은 관심사 분리입니다.우리는 항상 서비스 간과 서비스 자체 간의 코드 부분에 따라 이런 분리를 고려하지만, 이것은 더욱'인프라 시설'구성 요소에도 적용된다.응용 프로그램 코드는 기초 구조로 처리해야 할 일을 처리해서는 안 됩니다.
다음 코드는 고도로 결합된 응용 프로그램 코드 예시입니다.
const { createLogger, transports, winston } = require('winston');
const winston-mongodb = require('winston-mongodb');

// log to two different files
const logger = createLogger({
  transports: [
    new transports.File({ filename: 'combined.log' }),

  ],
  exceptionHandlers: [
    new transports.File({ filename: 'exceptions.log' })
  ]
});

// log to MongoDB
winston.add(winston.transports.MongoDB, options);
잠시 후 배포 환경 문제를 고려하지 않고 응용 프로그램 자체에 중점을 두겠습니다.
응용 프로그램이 로그 기록을 처리하도록 함으로써 이제 또 다른'문제'를 맡게 되었다.로그 출력을 정의함으로써 응용 프로그램은 현재 응용 프로그램/업무 논리와 로그 논리를 처리할 수 있습니다.
나중에 로그 위치를 변경해야 한다면 어떻게 해야 합니까?이것은 다른 코드 변경과 배치입니다. (QA/변경 제어/배치 과정이 많으면 더 필요합니다.)만약 로그 파일 이름이 틀리면 어떻게 합니까?마찬가지로 다른 코드가 변경되고 배치됩니다.
이것은 프로그램이 로그에 대해 극단적인 입장을 취해야 한다는 것이 아니라, 로그 문장을 피해야 한다는 것도 아니다. 왜냐하면 코드의 구성 요소를 결합시키고 프로그램 코드를 깨끗하게 유지하려면 로그 루트가 프로그램에 속하지 않는 다른 층을 추가해야 한다는 것이다.
다음
"It should not attempt to write to or manage logfiles. Instead, each running process writes its event stream, unbuffered, to stdout." (Side note: although it specifically mentions `stdout`, I take it to mean `stdout` and `stderr`, and cursory Google searches seem to confirm this.)

나는 왜 관심사 분리의 측면에서 파일과 데이터베이스 등 출력에 로그인하는 것이 좋은 방법이 아닌지 위에서 토론했다.그러나 이것이 바로 환경 문제가 해결되기 시작한 곳이다.
노드에 있습니다.js 응용 프로그램, 당신은 여전히 컨트롤러에 로그인하고 있습니다 (일반적으로 사용됩니다 console.log() 또는 console.error().
엔진 덮개 아래의 컨트롤러가 stdoutconsole.log()stderrconsole.error()에 인쇄되어 있기 때문에 이 모듈을 사용하면 우리는 마치 이 테스트를 통과한 것 같다.
이 테스트의 존재는 이유가 있다. 만약 당신이 이전에 물리적, 심지어 가상 (용기/클라우드가 아니라) 서버를 사용한 적이 있다면, 당신은 소수의 서버만 있을 수도 있고, 적어도 관리할 수 있는 크기가 있을 수도 있으며, 로그 파일, 그것들의 위치와 다른 설정을 수동으로 설정할 수 있다.
지금 상상해 보세요. 당신의 응용 프로그램은 이미 큰 성공을 거두었고 매일 수백 명의 새로운 사용자가 가입합니다.팀은 클라우드 기반 환경으로 이전하기 시작했습니다. 응용 프로그램을 필요에 따라 확장해야 합니다. 하나의 실례에서 50개로 확장해야 합니다.이 실례들이 어디에서 실행되는지 모르기 때문에 로그 파일의 정확한 쓰기 위치를 제어할 수 없습니다.
보유stream | target보다 유용하다.시냇물은 우리로 하여금 어느 곳에나 파이프를 깔고 강력한 파이프를 한데 조합할 수 있게 한다.Linux/Unix를 사용한 적이 있다면 흐름을 연결하기만 하면 파일의 텍스트를 검색할 수 있습니다: target -> (your routing solution) -> target.cat example.txt | grep sometext 너에게 이런 힘을 부여한다.예를 들어, 필요한 경우 stdout/stderr 파이핑을 통해 로그 파일로 전송할 수 있습니다.
그 밖에 클라우드 응용 프로그램은 짧다.그것들은 위로 회전, 아래로 회전, 붕괴 등을 할 수 있다는 것은 로그도 짧다는 것을 의미한다.
따라서 우리가 왜 응용 프로그램이 파일/데이터베이스/기타 지속적인 저장 목표의 루트 로그를 처리하지 말아야 하는지를 연구하기 시작했을 때, 이 목표에 로그인해도 됩니까?
다음
"In staging or production deploys, each process’ stream will be captured by the execution environment, collated together with all other streams from the app, and routed to one or more final destinations for viewing and long-term archival. These archival destinations are not visible to or configurable by the app, and instead are completely managed by the execution environment."

이것은 이 문제에 대답하는 데 도움이 된다.실행 환경이 stdout/stderr 로그에서 루트를 진행하면, 로그 루트를 지속적인 저장소로 옮길 수 있습니다. (사실, 절대로 이렇게 해야 합니다.)
이것 또한 이전에 말한 관심의 분리를 다시 한 번 확인했다.우리는 로그 파일이 어디에서 끝날지 확정할 수 없다.용기가 붕괴되면 로그 파일이 처음부터 로그 공유기에 주워지지 않으면 끝이다.프로그램이 붕괴된 원인을 디버깅할 때 행운을 빕니다.
멋지지만, 당신은 어떻게 생산 중에 일지를 관리합니까?stdout에 전송된 내용을 추출할 수 있는 도구가 있습니까?
실제로 이것이 로그 루트 부분의 용무지입니다. 이 글은 프로그램 코드에서 처리하는 것을 말리려고 합니다.
간단하게 말하자면, 구름 환경의 일부로 용기에 Docker 를 사용하고 있다고 가정하십시오.기본적으로 컨테이너가 아닌 Docker 호스트에서 실행되는 Docker 데몬 프로세스는 컨테이너stdout/stderr에서 로그를 추출합니다.
Docker 데몬 프로세스는 다음과 같이 실제 로그 라우팅 작업을 수행하여 지정된 스토리지 대상으로 추출하고 라우팅하도록 로그 드라이버를 사용하도록 구성할 수 있습니다.stdout/stderr 파일에서
{
  "log-driver": "splunk", // just using Splunk as an example, it could be another storage type
  "log-opts": {
    "splunk-token": "",
    "splunk-url": "",
    ...
  }
}
Dockerhere가 지원하는 로그 드라이버 목록을 볼 수 있습니다. 이 드라이버들은 로그를 선택하고 라우팅하는 역할을 합니다.이 목록에는 Greylog, Splunk, syslog, 그리고 익숙한 로그 집합기가 포함되어 있습니다.
로그 루트를 어딘가로 보내는 것이 중요합니다. 프로그램이 붕괴되고, 확장에 따라 시작되고, 확장에 따라 닫히는 상황에서 로그를 볼 수 있는 지속적인 저장 위치가 있습니다.
그러나 이 작업은 상술한 이유로 인프라 차원에서 이뤄져야 한다.
본 논문의 내용을 바탕으로 한 전체 로그 그림은 다음과 같다.

끝내다


어플리케이션에서 daemon.json 이외의 다른 어플리케이션으로의 라우팅을 처리하지 않으려는 이유 요약:
  • 애플리케이션 코드에서 로그 라우팅 책임을 제외합니다.
  • 코드를 더 깨끗하게 유지
  • 배포 없이 로깅 위치를 쉽게 변경할 수 있음
  • 애플리케이션/컨테이너를 확장하면 로그 파일을 더 쉽게 제어할 수 없음
  • 확장 프로그램도 더 짧다는 것을 의미하며, 로그 파일이 존재하지 않을 수도 있다는 것을 의미하며, 이것은 용기의 상태에 달려 있다
  • 파일이나 데이터베이스에 stdout/stderr 쓰기를 통해 로그 대상에 연결함으로써 stdout/stderr 출력을 원하는 대상에 전송하는 유연성을 박탈하고 동적 변경
  • 클라우드 환경이나 용기를 사용하지 않았다면 어떻게 해야 합니까?
    나의 생각은 아래와 같다.내가 여기서 제시한 방법은 여전히 유용하다. 왜냐하면:
  • 언젠가는 물리적 또는 가상 서버에서 클라우드/컨테이너 방법으로 전환하여 마이그레이션 경로를 사용자 자신이나 이 작업을 수행할 팀에게 더욱 쉽게 할 수 있습니다
  • 당신은 여전히 관심점의 분리를 유지합니다
  • 항상 "stdout"를 파이프라인을 통해 로그 파일이나 다른 지속적인 저장 대상으로 전송할 수 있으며, Docker 수호 프로세스와 같은 장점을 얻을 수 있습니다
  • 로그를 실현하거나 현재 로그 코드를 보고 있을 때, 로그 프레임워크를 stdout/stderrconsole.log() 과 비교하기로 결정하면 that can help you make the decision here 글을 썼습니다.여기에 있는 이 글을 기억하고 로그 프레임워크에서 console.error() 쓰기만 하면 다른 내용을 쓸 이유가 절대 없습니다.
    Node와 JavaScript를 쉽게 이해할 수 있도록 많은 새로운 내용을 작성하고 있습니다.더 간단하다. 왜냐하면 나는 그것이 때때처럼 복잡하다고 생각하지 않기 때문이다.만약 당신이 이 글을 좋아한다면, 그것은 here's that link again 나의 시사통신을 구독하는 데 도움이 된다는 것을 발견할 수 있을 것이다.

    좋은 웹페이지 즐겨찾기