Автоматический запуск профайлера в New Relic
Date November 19th, 2013 Author Vitaly Agapov
Несколько лет назад я уже писал статью про свой игрушечный Perl'овый скриптик, авторизующийся на странице. Новой практической задачи пришлось ждать довольно долго. Но она появилась. После недавнего обновления клиентов New Relic у них появилась возможность профилировать все потоки приложения (Java, Ruby, да хоть PHP), чтобы была возможность определить, в каких тредах и на каких методах происходит потеря времени. Запуск профайлера производится из веб-интерфейса, куда надо сначала залогиниться. А очень хотелось записывать дампы по расписанию или, допустим, по наступлению некоего события вроде слишком высокого времени ответа или высокой загрузки CPU.
А пол-дела уже и сделано. Осталось припомнить основы работы с модулем LWP::UserAgent и посмотреть firebug'ом, как проходит авторизация, подстановка CSRF-токенов и отправка форм в интерфейсе New Relic.
Дальше я просто приведу сам скрипт с разбросанными тут и там комментариями. Думаю, больше ничего не понадобится.
#!/usr/bin/perl use LWP::UserAgent; use HTML::Entities; use Data::Dumper; my $debug = 0; my $login = 'mylogin'; my $pwd = 'mypassword'; my $urlGetLogin = "https://rpm.newrelic.com/login"; my $urlPostLogin = "https://rpm.newrelic.com/session"; my $urlGetProfiler = "https://rpm.newrelic.com/accounts/my_acc_id/applications/my_app_id/profiles"; my $urlPostProfiler = "https://rpm.newrelic.com/accounts/my_acc_id/applications/my_app_id/profiles"; my $profileDuration = 2; my $ua = LWP::UserAgent->new; # Забираем страницу с формой логина и получаем куки с идентификатором сессии и находим CSRF-токен my $req = $ua->get($urlGetLogin); my $csrfToken = getToken($req->content); my $cookie = $req->{_headers}->{'set-cookie'}; my $uiSession = getSession($cookie); if (!$uiSession || !$csrfToken || !$req->{_msg} eq "OK") { print "Cannot get login page\n"; exit 1; } # Отправляем POST на логин, из которого опять забираем новые куки $req = $ua->post($urlPostLogin, [ 'authenticity_token' => $csrfToken, 'login[email]' => $login, 'login[password]' => $pwd, 'login[remember_me]' => 0, 'login[oauth_signin]' => '', 'utf8' => '✓', ], cookie => $cookie ); $cookie = $req->{_headers}->{'set-cookie'}; my $loggedIn = getLoggedIn($cookie); print Dumper($req) if ($debug); # Если в куке nr_zd_logged_in нет значения true, значит логин не удался и можно расходиться if ($loggedIn ne 'true') { print "Cannot login\n"; exit 1; } # Забираем страницу с формой запуска профайлера. Здесь нас опять интересует CSRF-токен, а также Agent-ID. $req = $ua->get($urlGetProfiler, cookie => $cookie ); $csrfToken = getToken($req->content); print Dumper($req) if ($debug); my $realAgentId = getRealAgentId($req->content); # И, наконец, POST на запуск профайлера. У нас есть кука с сессией, Agent-ID, CSRF-токен. В общем, всё для успешного запуска $req = $ua->post($urlPostProfiler, [ 'authenticity_token' => $csrfToken, 'profile[duration]' => $profileDuration, 'profile[real_agent_id]'=> $realAgentId, 'utf8' => '✓', ], cookie => $cookie ); # В случае успешного запроса мы должны вывести "ОК" print $req->{_msg}; print Dumper($req) if ($debug); exit 0; # Функции для парсинга заголовков и тел сообщений sub getToken { my $content = shift; if ($content =~ /<meta name="csrf-token" content="(.+?)"\/>/) { # В токене могут присутствовать HTML-коды, поэтому нам пригодится модуль HTML::Entities и функция decode_entities return decode_entities($1); } return 0; } sub getRealAgentId { my $content = shift; if ($content =~ /name="profile\[real_agent_id\]" type="radio" value="(\d+)"/) { return $1; } return 0; } sub getSession { my $cookie = shift; if ($cookie =~ /_newrelic_ui_session=(.+?);/) { return $1; } return 0; } sub getLoggedIn { my $cookie = shift; foreach (@{$cookie}) { if (/nr_zd_logged_in=(.+?);/) { return $1; } } return 0; }
Tags: Perl
Category:
Perl |
No comments »