2017-10-11 6 views
4

이것은 현재 나의 현재 문제에 관한 것이 아니지만 일반적으로 더 비슷합니다. 때로는 프로덕션 구성에서만 발생하는 문제가 있으며 거기에서 디버그하고 싶습니다. 엘릭서에서 가장 좋은 방법은 무엇입니까? 생산은 그래픽 환경 (도커)없이 실행됩니다.프로덕션 환경에서 Elixir 응용 프로그램을 디버깅하는 방법은 무엇입니까?

dev에서는 IEX.pry를 사용할 수 있지만 프로덕션 환경에서는 믹스를 사용할 수 없기 때문에 옵션이 아닌 것 같습니다.

Erlang의 경우 https://stackoverflow.com/a/21413344/1561489에 dbg 및 redbug가 언급되어 있지만 사용 가능하다고해도 필자는 Elixir 코드에 적용하는 데 도움이 필요합니다.

+3

를 사용하여 특정 로그는 항상 로그에 대한 기본 백엔드를 대체 할 수있는 사용자의 요구에 적합한 뭔가. – PatNowak

+1

로그를 디버깅, 재배포 및 감시하려는 모든 곳에서'Logger.error'를 추가하십시오. 나는 또한 더 나은 접근법에 대해 듣고 싶다. –

+0

또한 프로덕션 시스템과 디버그 시스템 간의 정확한 차이를 확인하고이를 제거 할 수 있습니다. 내가 아는 한 BEAM 코드의 관점에서 "디버그"빌드가 존재하지 않으므로 두 환경에서 코드가 동일해야합니다. –

답변

3

먼저, iex -S mix을 사용하여 dev 컴퓨터에서 iex를 실행하는 로컬 노드를 시작하십시오. 중단 점을 활성화하기 위해 로컬로 실행되는 응용 프로그램을 원하지 않으면 응용 프로그램을 로컬에서 시작하지 못하게해야합니다. 이렇게하려면 mix.exs에서 application 함수를 주석 처리하거나 iex -S mix run --no-start을 실행하면됩니다.

다음, 당신은 Node.connect(:"[email protected]")를 사용하여 디바이스 노드에 IEX에서 고정 표시기에서 실행되는 원격 노드에 연결해야합니다. 이를 수행하려면 원격 시스템의 epmd 및 노드 포트가 로컬 노드에서 도달 할 수 있는지 확인해야합니다.

마지막으로 노드가 연결되면 로컬 iex에서 :debugger.start()을 실행하면 GUI가있는 디버거가 열립니다. 이제 로컬 iex에서 :int.ni(<Module you want to debug>)을 실행하면 모듈이 디버거에 표시되고 중단 점을 추가하고 디버깅을 시작할 수 있습니다.

단계 및 스크린 샷 here으로 튜토리얼을 찾을 수 있습니다.

+0

감사합니다, 이것은 내가 찾고있는 대답입니다! – raarts

+0

IEx 매뉴얼에서 다음을 추가하고 싶습니다. "원격 셸에 연결하는 것은 너무 일반적이어서 명령 줄을 통해서도 바로 가기를 제공합니다 :'$ iex --sname baz --remsh foo @ HOST'" – raarts

0

나는 지금까지 내가 Sentry에 큰 경험을 데, 예외 처리 도구의 일종을 사용하는 것이 좋습니다 것입니다.

0

AWS에서 프로덕션을 실행하는 경우 가장 먼저 CloudWatch을 활용해야합니다. 같은 위치를 정확히 erl_crash.dump에 대한 환경 변수를 구성하여 Dockerfile 내부

config :logger, 
    handle_otp_reports: true, 
    handle_sasl_reports: true, 
    metadata: [:application, :module, :function, :file, :line] 

config :logger, 
    backends: [ 
    {LoggerFileBackend, :shared_error} 
    ] 

config :logger, :shared_error, 
    path: "#{logging_dir}/verbose-error.log", 
    level: :error 

를 기록됩니다 : ERL_CRASH_DUMP=/opt/log/erl_crash.dump

는 그 다음 .config 내부 awslogs를 구성하여 elixir 코드에서 이 같은 로거를 구성 .ebextensions 아래 파일 :

files: 
    "/etc/awslogs/config/stdout.conf": 
    mode: "000755" 
    owner: root 
    group: root 
    content: | 
     [erl_crash.dump] 
     log_group_name=/aws/elasticbeanstalk/your_app/erl_crash.dump 
     log_stream_name={instance_id} 
     file=/var/log/erl_crash.dump 

     [verbose-error.log] 
     log_group_name=/aws/elasticbeanstalk/your_app/verbose-error.log 
     log_stream_name={instance_id} 
     file=/var/log/verbose-error.log 

u는 그 후, 당신은 CloudWatch 아래 오류 메시지를 검사 할 수 있습니다 Dockerrun.aws.json

"Logging": "/var/log", 
    "Volumes": [ 
    { 
     "HostDirectory": "/var/log", 
     "ContainerDirectory": "/opt/log" 
    } 
    ], 

아래에 고정 표시기에 볼륨을 설정합니다. AWS ECS 반대로 당신이 Docker 배포 (내 예를 들어 위의 암시 적 의미하는) ElasticBeanstalk를 사용하는 경우 는 지금, 다음 std_input의 로그는 CloudWatch 내부 /var/log/eb-docker/containers/eb-current-app/stdouterr.log 기본적으로 리디렉션됩니다.

erl_crash.dump의 주요 목적은 응용 프로그램이되어 컨테이너를 복용, 추락 할 때 적어도 알고있다.AWS EB은 일반적으로 컨테이너를 다시 시작하므로 다시 시작하는 것에 대해 무지하게 유지됩니다. 이러한 이해는 다른 도커 관련 로그에서도 얻을 수 있으며, 알람을 수신 대기하도록 구성하여 도커를 다시 시작해야 할 때 알릴 수 있습니다. 그러나 CloudWatch를에 erl_crash.dump 로깅의 또 다른 장점은 필요하다면, 당신은 항상, S3 나중에 내보낼 파일을 다운로드하고 무엇이 잘못되었는지 분석을 할 :observer 내부 가져올 수 있다는 것입니다. 로그를 컨설팅 한 후, 당신은 여전히 ​​당신의 생산 응용 프로그램과 더 친밀한 상호 작용이 필요한 경우

는, 당신은 당신의 노드에 remsh을 활용해야합니다.

rel/confix.exs 내부 설정 쿠키 :

environment :prod do 
    set include_erts: false 
    set include_src: false 
    set cookie: :"my_cookie" 
end 

rel/templates/vm.args.eex에서 사용자가 설정 한 변수 :

당신이 distillery를 사용하는 경우 cookie이처럼 릴리스 생산 응용 프로그램의 node name을 구성합니다
-name <%= node_name %> 
-setcookie <%= release.profile.cookie %> 

rel/config.exs의 경우 다음과 같이 설정합니다.

당신이 할 수있는,

CONTAINER_ID=$(sudo docker ps --format '{{.ID}}') 
sudo docker exec -it $CONTAINER_ID bash -c "iex --name [email protected] --cookie my_cookie" 

을 한 번 내부 :

release :my_app do 
    set version: "0.1.0" 

    set overlays: [ 
    {:template, "rel/templates/vm.args.eex", "releases/<%= release_version %>/vm.args"} 
    ] 

    set overlay_vars: [ 
    node_name: "[email protected]", 
    ] 

10 그럼 당신은 바로 다음 첫 번째 SSH 오링 고정 표시기 컨테이너를 수용하는 EC2 인스턴스 내부에 의해 고정 표시기 내에서 실행 생산 노드에 연결하고 실행할 수 있습니다 그런 다음 주위를 두드 리거나 if need be, 자신의 위험에 따라 검사하려는 모듈의 수정 된 코드를 동적으로 주입하십시오. 쉬운 방법은 컨테이너 내부에 파일을 작성하여 호출하는 것입니다. Node.spawn_link target_node, fn Code.eval_file(file_name, path) end

프로덕션 노드가 이미 실행 중이며 쿠키를 모르는 경우 실행중인 컨테이너에 들어가서 다음을 수행 할 수 있습니다. ps aux > t.log 및 임의의 쿠키를 적용하고 그에 따라 사용 된 내용을 파악하기 위해 cat t.log을한다.

고정 표시기 epmd는 다른 노드와 통신 할 수있는 방법에 걸림돌로 작용한다. 가장 좋은 그러므로 오히려 Packer를 사용하여 자신의 AWS AMI 이미지를 만드는 대신 베어 메탈 배포를 수행하는 것입니다.

아마존은 최근 AWS ECS, AWS VPC Networking Mode에 새로운 기능을 출시했습니다. 이것은 아마도 컨테이너 간 상호 통신을 용이하게하여 노드에 직접 연결될 수 있습니다. 나는 그것을 아직 시도하지 않았다, 나는 틀릴지도 모른다.

AWS 이외의 제공 업체에서 실행중인 경우 SSM agent 또는 다른 서비스로 원격 로그에 쉽게 액세스하는 방법을 알아내는 것이 필수입니다. 콘솔 - -

+0

위의 내용은 일반적인 개요이며, 자세한 내용은 빠져있을 수 있으며 독자의 연습 문제로 남아 있습니다.) –