<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Корчагин Станислав &#187; мониторинг</title>
	<atom:link href="http://korchasa.ru/index.php/tag/%d0%bc%d0%be%d0%bd%d0%b8%d1%82%d0%be%d1%80%d0%b8%d0%bd%d0%b3/feed/" rel="self" type="application/rss+xml" />
	<link>http://korchasa.ru</link>
	<description>Разработка, тестирование, запуск</description>
	<lastBuildDate>Mon, 24 May 2010 23:28:58 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Сеанс консольной магии: анализ access логов nginx&#039;а.</title>
		<link>http://korchasa.ru/index.php/2008/11/%d1%81%d0%b5%d0%b0%d0%bd%d1%81-%d0%ba%d0%be%d0%bd%d1%81%d0%be%d0%bb%d1%8c%d0%bd%d0%be%d0%b9-%d0%bc%d0%b0%d0%b3%d0%b8%d0%b8-%d0%b0%d0%bd%d0%b0%d0%bb%d0%b8%d0%b7-access-%d0%bb%d0%be%d0%b3%d0%be%d0%b2-n/</link>
		<comments>http://korchasa.ru/index.php/2008/11/%d1%81%d0%b5%d0%b0%d0%bd%d1%81-%d0%ba%d0%be%d0%bd%d1%81%d0%be%d0%bb%d1%8c%d0%bd%d0%be%d0%b9-%d0%bc%d0%b0%d0%b3%d0%b8%d0%b8-%d0%b0%d0%bd%d0%b0%d0%bb%d0%b8%d0%b7-access-%d0%bb%d0%be%d0%b3%d0%be%d0%b2-n/#comments</comments>
		<pubDate>Fri, 07 Nov 2008 04:29:00 +0000</pubDate>
		<dc:creator>korchasa</dc:creator>
				<category><![CDATA[Статьи]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[мониторинг]]></category>
		<category><![CDATA[производительность]]></category>

		<guid isPermaLink="false">http://korchasa.ru/?p=31</guid>
		<description><![CDATA[О том, что где-то рядом живут sed, grep, awk и pipelines, я узнал еще года 4 назад, но  использовать (с толком) их не приходилось. Пока не захотелось странного&#8230;

Странное заключалось в поиске запросов от парсеров в логе nginx&#8217;а, и в поиске &#8220;дорогих&#8221; страниц.
Оказалось все просто:


sed &#8211; потоковый редактор текста. Т.е. ты ему поток текста, а [...]]]></description>
			<content:encoded><![CDATA[<p>О том, что где-то рядом живут sed, grep, awk и pipelines, я узнал еще года 4 назад, но  использовать (с толком) их не приходилось. Пока не захотелось странного&#8230;</p>
<p><span id="more-31"></span></p>
<p>Странное заключалось в поиске запросов от парсеров в логе nginx&#8217;а, и в поиске &#8220;дорогих&#8221; страниц.<br />
Оказалось все просто:<span style="font-weight: bold;"><br />
</span>
<ul>
<li><a href="http://en.wikipedia.org/wiki/Sed"><span style="font-style: italic;">sed</span></a> &#8211; потоковый редактор текста. Т.е. ты ему поток текста, а он его преобразует по данным тобою правилам.</li>
<li><a href="http://en.wikipedia.org/wiki/Grep"><span style="font-style: italic;">grep</span></a>- потоковый фильтр. Ты ему критерий, он тебе данные, отфильтрованные по этому критерию.
</li>
<li><a href="http://en.wikipedia.org/wiki/Awk"><span style="font-style: italic;">awk</span></a> &#8211; скриптовый язык для обработки потоков. Мощная штука. Очень мощная штука.
</li>
</ul>
<h3>А теперь хором</h3>
<p>   Задача номер один &#8211; поиск парсеров. Парсеры отличаются тем, что делают много запросов с одного IP. Понеслась&#8230;</p>
<p>Файл <span style="font-weight:bold;">group_by_ips.sh</span>:</p>
<pre lang="PHP">awk '
{
  requests_count_from_ips[$1]++
}
END
{
  for (ip in requests_count_from_ips)
  {
    print requests_count_from_ips[ip] ": " ip;
  }
}' | \
sort -nr</pre>
<p>Создаем массив, в котором в качестве ключей используем IP, а в качестве значений &#8211; количество запросов с него. Т.к. IP в access логе у нас стоит первым, то соответственно его значение попадет в скрипт, как $1. По окончанию обработки потока бежим по массиву и выводим первым &#8211; количество запросов, а потом IP. Ну и сортируем вывод sort&#8217;ом.</p>
<pre lang="PHP">#cat ./access.log | ./group_by_ips.sh | head
81015: 66.249.72.83
11740: 69.80.244.163
6527: 82.193.155.236
2456: 88.212.197.90
1833: 195.131.145.226
1770: 67.202.41.3
1584: 195.208.157.26
1544: 89.239.140.106
1235: 89.252.9.34
1208: 72.26.227.114
</pre>
<h3>Мы для кого работаем?</h3>
<p>   Задача #2 состоит в определении &#8220;стоимости&#8221; различных url. Стоимостью мы будем считать время работы backend&#8217;а. Для того, чтобы он попал в access лог будем использовать переменную &#8220;upstream_response_time&#8221;. Формат моих логов:</p>
<pre lang="PHP">log_format fastcgi_log '$remote_addr $request $status $body_bytes_sent'
' $http_referer $upstream_response_time $request_time $time_local $host [$http_user_agent]';</pre>
<p>Файл <span style="font-weight: bold;">calc_weights_by_urls.sh</span>:
<pre lang="PHP">awk '{
  gsub(/[0-9]+/, "X", $3);
  urls[$2" "$3] += $8;
}
END
{
  for(i in urls)
  {
    print urls[i]":"i;
  }
}' | \
sort -nr</pre>
<pre lang="PHP">#cat ./access.log | ./calc_weight_by_urls.sh | head
88160.2:GET /users/X/
85643.6:GET /photos/X/
84629.4:GET /photos/category/X/?pager=X
45453.2:GET /photos/X/?from_member
25910:GET /users/X/?pager=X
9275.3:GET /photos/category/X/
8299.5:GET /
8298.21:GET /users/X/photos/?category=X
4309.97:GET /my/favorite_authors_photos/
4304.44:GET /new_on_site/photos/?pager=X</pre>
<h3>Коль пошла такая пьянка</h3>
<p>Раз уж у нас есть данные по стоимости каждого запроса, то можно улучшить решение первой задачи, и считать стоимость IP не по количеству запросов, а как сумму стоимостей запросов с этого IP.<br />
Файл <span style="font-weight: bold;">calc_weights_by_ips.sh</span>:</p>
<pre lang="PHP">awk '
{
  ips[$1] += $8;
}
END
{
  for(i in ips)
  {
    print ips[i]":"i;
  }
}' | \
sort -nr
</pre>
<pre lang="PHP">
cat ./access.log | ./calc_weight_by_ips.sh | head
42533.1:66.249.72.83
12886.8:69.80.244.163
5272.19:82.193.155.236
3892.73:93.189.148.97
1678.77:88.212.197.90
1424.76:67.202.41.3
1327.53:82.207.122.195
1318.4:81.19.66.89
1199.44:67.195.45.213
1114.04:80.72.18.82
</pre>
<p>В итоге три первых IP сохранились, а дальше уже картина немного другая.</p>
<h3>Немного о скорости</h3>
<p>Несмотря на то, что я, мягко говоря, не айс в этих утилитах, и скорее всего написал все криво и неоптимально, но скорость все равно радует:</p>
<ul>
<li>размер анализируемого лога &#8211; 160Mb (650К строк)</li>
<li>время работы подсчета стоимости по IP &#8211; 2 секунды</li>
<li>время работы подсчета стоимости по урлам &#8211; 4 секунды</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://korchasa.ru/index.php/2008/11/%d1%81%d0%b5%d0%b0%d0%bd%d1%81-%d0%ba%d0%be%d0%bd%d1%81%d0%be%d0%bb%d1%8c%d0%bd%d0%be%d0%b9-%d0%bc%d0%b0%d0%b3%d0%b8%d0%b8-%d0%b0%d0%bd%d0%b0%d0%bb%d0%b8%d0%b7-access-%d0%bb%d0%be%d0%b3%d0%be%d0%b2-n/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
	</channel>
</rss>
