среда, 10 октября 2012 г.

В сотый раз rsyslog...

    В стопиццотый раз хотелось бы затронуть тему централизованного ведения логов.
Рано или поздно, любой системный администратор,  задается вопросом "Как бы сделать так что бы еще больше ничего не делать...?" И тут уже начинается и полет фантазии, и автоматизация, и изучение языков программирования и так далее. Прилагаются титанические усилия в кратчайшие сроки, что в переводе на "работо-часы" означает что проделанной работы хватило бы на целый квартал, но нет же !!! Нужно обязательно поделить работу на 0 - иначе это будет не True....
    Размышляя в данном направлении можно прийти к мысли что просматривать логи на серверах (и прочих железяках) вещь конечно нужная, и часто много легче предупредить беду обнаружив, что на сервере начал сыпаться винт, чем придя на работу получать суть накала быстро соображая как теперь восстановить работоспособность груды железа и понять причины выхода его из строя. Но здесь мы натыкаемся на несколько неприятных моментов, потому что нужно каждый день тратить какое-то время что бы "зайти" на все важные сервера,
просмотреть логи, проанализировать ошибки, и так далее. Занятие монотонное и утомительное, и как правило на него ложат уже через неделю. Да, можно настроить сервер логов, на котором собирать логи со всех устройств. Но опять же, нужно кому то сидеть и смотреть эти логи - что в разрезе айтишника не имеет ничего общего. Исходя из таких вот негативных мыслей, Мы попытаемся сегодня настроить свой сервер централизованного хранения логов с блекджеком и шлюхами. И так подытожим, мы хотим что бы:

1. Сервер собирал логи на себя со всевозможных устройств (включая никрасофт)
2. Был бесплатен
3. Был гибок в настройке
4. Фильтровал сообщения
5. Мог отправлять админу почту с указанием источника и ошибки
6. Хранил логи в БД (мало ли, придет начальство а ты такой "ОППА" и хмуря брови смотришь лог....) --- ну вообще много для чего нужно на самом деле...

Итого, порывшись в тырнете и опробовав несколько вариантов сделал такие выводы:
Стандартный syslog - хорошо что везде есть, плохо что ограничен во всем.
syslog-ng (типа нью генерайшен) - уже много луче, но есть грабли с фильтрами и не поддерживает отправку писем из коробки.
Rsyslog - жуткий демон, может все что нужно, все в комплекте, но дурацкий синтаксис конфига и, к тому же, отличающийся в разных версиях !!! Эврика ! Это же то что нам нужно, и мозги размять и дело сделать и медаль на грудь себе потом повесить!!!
Итого, берем какое-то железяко или виртуалку, ставим на нее любую любимую вами *nix систему и принимаемся за настройку. Моей любимой системой в данный час оказалась 
FreeBSD Logs 9.0-RELEASE-p4 (Logs - имя машинки)
Итак , предположим что у нас чистая, только что установленная система
установим необходимое из портов (на линуксе ставим своим методом):
cd /usr/ports/sysutils/rsyslog6 && make install clean 
cd /usr/ports/sysutils/rsyslog6-mysql && make install clean
(обратите внимание я взял 6 версию, и мой конфиг на 5 работать не будет, на счет 7 не знаю)
cd /usr/ports/databases/mysql55-server && make install clean
cd /usr/ports/databases/mysql55-client && make install clean
Для начала вроде как хватит, теперь лезем в rc.conf  и добавляем правила:
mysql_enable="YES"
syslogd_enable="NO"
rsyslogd_enable="YES"
rsyslogd_pidfile="/var/run/syslog.pid"
rsyslogd_flags="-c4"
Далее нам необходимо настроить rsyslog.conf - в мануале написанно что он у вас появится там-то и там-то, но у меня фокус не сработал и потому создаем его сами:
# touch /usr/local/etc/rsyslog.conf
Ниже я приведу свой конфиг, и постараюсь по максимуму его прокомментировать. В конфиге я   старался затронуть основные моменты нужные нам для работы, хотя возможности самого  rsyslog выходят далеко за рамки этой статьи и натворить в нем реально можно что угодно.
Некоторые моменты в конфиге вам будут не понятны, но по мере прочтения все станет на свои места...
Итак:
# cat /usr/local/etc/rsyslog.conf

#Модули которые нам нужны для работы необходимо явно указывать
#Добавим логирование локалхоста
$ModLoad imuxsock # provides support for local system logging
$ModLoad imklog   # provides kernel logging support (previously done by rklogd)
# Модуль отвечающий за прослушку по  UDP порту
$ModLoad imudp
# Порт сервера на котором слушать логгеров
$UDPServerRun 514
# Если не хотим что бы ломилось все в подряд, ограничим тех кто может ложить логи
$AllowedSender UDP, 127.0.0.1, 192.168.0.9, 192.168.0.141
#Поддержка БД MySQL (вобще ест поддержка и постгреса и т.д.)
$ModLoad ommysql#Настройки для отправки почты
$ModLoad ommail#smtp сервер
$ActionMailSMTPServer my.mail.server
#От кого будем получать логи
$ActionMailFrom report@my.mail.server
#Кому отправлять логи
$ActionMailTo report@my.mail.server
#Интересная штука темплейты. По сути что-то типа переменных но явно указанных.
#Напишем парочку темплейтов. с темой письма и содержимым для двух вариантов
#1 - для отправки сообщений с ошибками и 2 для отправки сообщений о ннедоступности хоста
#1
$template mailSubject,"ServerLog: Warning on %hostname%"
$template mailBody,"SERVERLOG\r\nError on  %hostname%\r\nError  =  '%msg%'"
#2
$template mailBodyPing,"SERVERLOG\r\nThe %hostname% is DOWN"
#Нужно обьявить тему для почты.
$ActionMailSubject mailSubject
#Настройки вида отображения логов оставим по умолчанию, хотя вы можете сделать свои
$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat
#Ну тут все понятно. Укажем кто хозяин логофайлов на сервере.
$FileOwner root
$FileGroup wheel
$FileCreateMode 0640
#Далее список правил для локалхоста, особо обьяснять не буду так как ето стандартные
#значения из сислога
# Log all kernel messages to the console.
kern.*                                                 /dev/console
# Log anything (except mail) of level info or higher.
*.info;mail.none;authpriv.none;cron.none                /var/log/messages
# The authpriv file has restricted access.
authpriv.*                                              /var/log/security# Log all the mail messages in one place.
mail.*                                                  -/var/log/maillog
# Log cron stuff
cron.*                                                  /var/log/cron# Everybody gets emergency messages
*.emerg                                                 *
# Save news errors of level crit and higher in a special file.
uucp,news.crit                                          /var/log/spooler
# Save boot messages also to boot.log
local7.*                                                /var/log/boot.log
#А вот теперь начинается магия...
#Создадим фильтры.
#Создадим фильтр, который следит за сообщениями в локальном сислоге, и
# если сообщение имеет в себе слово Alarm  то выполняем действие, а именно
# отправляем ошибку в базу данных и отсылаем админу письмо!
# синтаксис почты понятен. А для базы данных (щас создадим) он такой
:ommysql:servernamr,DB_name,username,password
# например у нас сервер локальный, имя базы = LogDB, пользователь = user, пароль =123
# тогда получим :ommysql:localhost,LogDB,user,123
#(Фильтрация по слову в сообщении $msg)
if $msg contains 'Alarm' then {
:ommail:;mailBodyPing :ommysql:localhost,LogDB,user,123
}
#Теперь добавим фильтр который например будет писать в БД все логи
#которые пришли к нам с айпишнека 10.0.0.10 (ну например это точка доступа)
#Filter to 10.0.0.10
if $hostname-ip == '10.0.0.10'  then :ommysql:localhost,LogDB,user,123
# Но возможно вам не нужен весь хлам, тогда добавим условие на вторую точку доступа # с которой будем писать только логи с меткой ERROR
if ($hostname-ip == '10.0.0.10' and $msg contains 'ERROR') then ommysql:localhost,LogDB,user,123
#И пожалуй самый интересный фильр, ето парсить логи от нужного нам виндовго сервера,
# писать их а базу данных, но если сообщение сожерит ошибку - отправлять его на почту.
# По умолчанию у rsyslog есть замечательные фильтры. Воспользуемся ими
# (Очень рекомендую при создании фильтров юзать сей чудо мануал ТЫЦ-ТЫЦ)
#Зафильтруем по имени ПК и типу ошибки, что согласно мануала означает что отправлять на
# почту только логи попадающие в категорию
0KERNЛог сообщения генерируемые ядром
1USERЛог сообщения генерируемые процессами пользователя
2MAILЛог сообщения от почтовой системы
3DAEMONЛог сообщения генерируемые системными демонами

if ($hostname == 'MOSTDIE' and $syslogseverity <= 3) then {
:ommail:;mailBody }
if ($hostname == 'MOSTDIE') then {
ommysql:localhost,LogDB,user,123
}

Для начала этого более чем достаточно! Сохраняем его !
И как и писалось раньше создадим базу данных и таблицы в ней (подразумевается что вы уже запустили Mysql и назначили пароль на рута)
mysql -u root -p yourpassword
mysql
вводим

mysql>  create database LogDB;
mysql> grant all privileges on LogDB.* to 'user'@'%' identified by '123' with grant option;
и создаем таблицы 
mysql> use LogDB;
mysql>
DROP TABLE IF EXISTS `SystemEvents`;
CREATE TABLE `SystemEvents` (
  `ID` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `CustomerID` bigint(20) DEFAULT NULL,
  `ReceivedAt` datetime DEFAULT NULL,
  `DeviceReportedTime` datetime DEFAULT NULL,
  `Facility` smallint(6) DEFAULT NULL,
  `Priority` smallint(6) DEFAULT NULL,
  `FromHost` varchar(60) DEFAULT NULL,
  `Message` text,
  `NTSeverity` int(11) DEFAULT NULL,
  `Importance` int(11) DEFAULT NULL,
  `EventSource` varchar(60) DEFAULT NULL,
  `EventUser` varchar(60) DEFAULT NULL,
  `EventCategory` int(11) DEFAULT NULL,
  `EventID` int(11) DEFAULT NULL,
  `EventBinaryData` text,
  `MaxAvailable` int(11) DEFAULT NULL,
  `CurrUsage` int(11) DEFAULT NULL,
  `MinUsage` int(11) DEFAULT NULL,
  `MaxUsage` int(11) DEFAULT NULL,
  `InfoUnitID` int(11) DEFAULT NULL,
  `SysLogTag` varchar(60) DEFAULT NULL,
  `EventLogType` varchar(60) DEFAULT NULL,
  `GenericFileName` varchar(60) DEFAULT NULL,
  `SystemID` int(11) DEFAULT NULL,
  `processid` varchar(60) NOT NULL DEFAULT '',
  PRIMARY KEY (`ID`)
);
DROP TABLE IF EXISTS `SystemEventsProperties`;
CREATE TABLE `SystemEventsProperties` (
  `ID` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `SystemEventID` int(11) DEFAULT NULL,
  `ParamName` varchar(255) DEFAULT NULL,
  `ParamValue` text,
  PRIMARY KEY (`ID`)
);

 Итог, конфиг настроен, база данных создана - перегружаемся и смотрим что получилось.
Если вы ничего не упустили и вдумчиво копировали конфиг, у Вас должен работать лог и rsyslog должен собирать данные с других ресурсов. Настройкой которых мы кстати сейчас и займемся. 
    Для того что бы наш мегаблекджек получал сообщения от серверов в сети, необходимо на этих самых серверах указать пересылать на него логи. Там где у вас установлен *nix проблем вообще никаких не возникает. Все штатно, стандартно и красиво и информации в гугле более достаточно. Но вот касаемо вопроса никрософта - пришлось таки опять читать много букав и подбирать варианты. Методом исключений был выбран победитель 
Инструмент идеально прост, стабилен, удобен - но главное полностью удовлетворяет наши запросы, а именно:
1. Легко устанавливается
2. Имеет встроенный фильтр
3. Устанавливается как служба
4. Отправляет все логи Виндаусов на указанный сервер.
Итого качаем архив под свою платформу. Распаковываем и копируем из него два файла evtsys.dll и evtsys.exe  в c:\windows\system32
Что Вам нужно знать о evtsys ? В целом можете посмотреть хелп и доступные опции. Но на данном этапе ограничимся следующим:
Установим его как службу и укажем куда хранить логи 
cd c:\windows\evtsys.exe -i -h 192.168.0.1  (192.168.0.1 - айпи нашего лог сервера)
после чего перейдем в службы и запустим службу "Event to Syslog"
для проверки создадим батник с таким вот содержимым и выполним его:

EVENTCREATE /T ERROR /ID 100 /L SYSTEM /D "Oshibka type" /SO "CMD file"
EVENTCREATE /T WARNING /ID 111 /L SYSTEM /D "Atention type" /SO "Cmd File"

Получим в журнал ошибок два сообщения, одно со статусом еррор, второе варнинг ! 
(В конфиге вместо MOSTDIE укажите имя машинки на котрой установили evtsys  и перезапустите rsyslog)
Смотрим журнал логов 
# tail -f /var/log/messages
Если все сделано верно вы получите в сислог два сообщения, оба запишутся в базу данных, но на почту прийдет только одно письмо, с темой и содержанием ошибки.
Кстати, интересный вариант. Если вы не планируете писать логи в разные базы данных, или не хотите писать фильтры для всех виндомашин можно воспользоваться специальным фильтром 
Facility - у которого на данный случай есть встроенные локальные переменные (Local0 -local7)
тогда правило в конфиге рсислога выглядело бы так (заюзаем local2)
local2.*  ommysql:localhost,LogDB,user,123  
а при установке evtsys укажем писать все свои логи в локальную переменную этого типа
evtsys.exe -i -f 18 -h 192.168.0.1  (-f 18 как раз наша переменная локал2 - читаем ман)
Ну вот в целом наша система и настроена. Уже можно пользоваться. Так же можно прикрутить к ней какую-то веморду типа loganalyzer и так далее которых в нете так же предостаточно (но я планирую написать свой, так что рассматривать в этой статье установку вебморды не буду). В целом - конфиг получился достаточно большой, и в нем много лишнего - но я постарался описать в нем все необходимые моменты нужные для работы. И очень жаль что я нигде не нашел столько манов в одном месте. Вся эта статья собрана по крупицам, а некоторые моменты пришлось выяснять методом подбора. По этому я надеюсь кому-то мой труд облегчит жизнь...
    Итого, имеем свой блекджек со шлюхами как и хотели. Но девочки у нас не очень - надо бы их еще причесать для порядку. Мы же хотим что бы наш сервер, кроме всего прочего, опрашивал кучу айпишнеков в сети, и если чото не пингонулось - сообщать нам опять же на почту!!! Тут уже вы сами можете выбрать готовое решение или написать скрипт на шеле, но в я лично пошел таким путем:
    Пишем скрипт который опрашивает ойпишнеки и если не пингеует выдает сообщение в сислог (А там у нас в засаде фиильтр который моментально реагирует и шлет письмо в начале конфига мы говорили об этом  
#(Фильтрация по слову в сообщении $msg)
if $msg contains 'Alarm' then {
:ommail:;mailBodyPing :ommysql:localhost,LogDB,user,123
}  )

    Смешно звучит, но я за все время использования *nix систем так и не заставил себя выучить написание скриптов на баше, по сему предлагаю свой скрипт на pythone. В нем есть список айпишнеков которые нужно опрашивать, и в случае ошибки он дает месадж в сислог. Опять же - некоторые скажут а почему список айпишнеков в самом скрипте а не в отдельном файле который можно редактировать - отвечаю - потому что список составляется как правило один раз и весьма редко когда нужно его править, и ради етого добавлять усложнять скрипт чтением файла, и хранить его гдето я не вижу смысла. Если у вас есть такое желание допишите сами, даже не зная языка сделать это очень просто так как в официальных доках есть примеры. Итого сам скрипт (Внимание. Скрипт на питоне - пробелы и переносы сохранять):
# touch /usr/local/bin/checkiplist
chmod +x /usr/local/bin/chekiplist
#cat /usr/local/bin/chekiplist


#!/usr/local/bin/python
import subprocessimport time
import os
"""IP list tu ping"""
iplist = ['192.168.0.9', '192.168.0.141', '192.168.90.141']
"""Chek time. If time from 7 to 18 then chek every minute, else every hour"""
def checkTime():
    cmdtime = int(time.strftime('%H'))
    if (cmdtime >= 7 and cmdtime <= 18):
        return time.sleep(60)
    else:
        return time.sleep(600)

def pingProcess(ip):
    pingTest = "ping -c 1 " + ip    process = subprocess.Popen(        pingTest, shell=True, stdout=subprocess.PIPE)
    process.wait()
    returnCodeTotal = process.returncode    if returnCodeTotal == 0:
        pass    else:
        return os.system('logger "Alarm "' + ip + ' is Down')

def cykle():
    for i in iplist:
        pingProcess(i)
counter = 1
while counter == 1:
    checkTime()
    cykle()


Ну и добавим красивый старт скрипта черег демон rc.d
# touch /usr/local/etc/rc.d/iplist.sh
chmod +x /usr/local/etc/rc.d/iplist.sh

cat /usr/local/etc/rc.d/iplist.sh

#!/bin/sh
#
# PROVIDE: iplist
# REQUIRE: DAEMON
# KEYWORD: shutdown
. /etc/rc.subrname=iplist
command="/usr/local/bin/chekiplist &"
load_rc_config $name
iplist_enable=${iplist_enable-"NO"}
pidfile=${iplist_pidfile-"/var/run/iplist.pid"}
run_rc_command "$1"
 и незабываем добавить в rc.conf строчку
iplist_enable="YES"

Ну вот и все! Теперь мы ленивые админы, все что остается - мониторить одним глазом почту
Удачи!





четверг, 27 сентября 2012 г.

Qtile


Qtile is a full-featured, hackable tiling window manager written in Python.

Начнем с азов, или почему я люблю Gentoo Linux?

    В последнее время с выходом "гладкошерстной" убунты, и прочих дистрибутивов заточенных, грубо говоря под мелкомягких, сеть переполнена людьми, которые установив в "три тычка" какой либо дистрибутив - гордо именуют себя не иначе как "Линуксоидами". При этом, понятия не имея как работает система и где настраивается мышка, и любой мелкий баг в случае если не работают окошки, превращается в нерешаемую проблему и обсуждение на форуме в cтопиццотый раз одного и того же вопроса не менее чем 50 постов...
    То ли дело "Гента". Установка сложна и этот природный барьер отсеивает как раз вышеописанную категорию юзеров. Поэтому факи и хелпы по генте по сравнению с другими дистрами настолько хороши и подробны. Большинство пользователей Gentoo это категория людей, которые хорошо разбираются в *nix системах и которых достали тяжеловесные, глючные и попросту ненужные в работе окошки, няшки, рамки, красивые нештяки и прочая поебень включая таких гигантов как гном, кеды или крыса...
    Вот как раз эти люди, ставят чистую систему и сугубо под себя настраивают маленькие, функциональные и очень шустрые и стабильные графические оболочки такие как IceWM, FVWM, OpenBOX и так далее. Для сравнения - гномы, кеды, крысы и так далее это всего лишь табуретка, с какой стороны не сядь - все равно жопе не удобно. Да, для настройки перечисленных мелких ВМ необходимо время что бы разобраться с конфигами, но на выходе вы получаете удобное кресло со спикой и подлокотниками....
    Но все выше перечисленное имеет все же, на мой взгляд, один дефект - много лишних графических обьектов на экране, которые расчитаны делать работу за ПК более приятной, но на самом деле - просто отвлекающих пользователя. И тут, для самых требовательных задротов (пример Автор), приходят на помощь Тайловые менеджеры. Читать
    На данный момент выбор достаточно широк и существует как минимум несколько стабильных продуктов обладающих своими плюсами и минусами. Основные продукты это DWM, Xmonad, wmii, Ion3, awesome - из которых можно выделить лишь последних
два, как достаточно юзабельных. В свое время окончательно устав от всей этой лишней шушеры я принял решение перейти на тайловый ВМ и перепробовал их все, остановив в конце концов свой выбор на awesome. Он не был идеален, но количество моментов которые запросто могу повесить компьютер пентагона своей логикой значительно меньше по сравнению с конкурентами.
    Поработав некоторое время напильником, я привел его к желаемому виду, с нужными мне виджетами, хоткеями и так далее.  И реально работать за ПК стало действительно приятно и удобно. На экране всегда тольно нужная вам информация, в нужном вам месте, в нужное время и в нужном виде. Все управление и перемещение осуществляется посредством клавиатурных комбинаций, по сему дебильная мышка нужна в редких случаях - а следоватьльно обе ваши руки постоянно находятся на клавиатуре, что опять же облегчает набор текста  и так далее... Но великий Awesome обладал, на мой взгляд, весьма
ощутимым недостатком. Его конфиг написан на Lua. В целом - конечно не очень страшно если вам нужно парочка написанных кем-то виджетов, но для того что бы максимально натсроить все как вам хоетлось бы - нужно таки его учить. И тут у меня встал вопрос. По сути я занимаюсь системным администрированием, и у меня даже было время заняться изучением языка, но размышления в направлении "Учить язык программирования для того что бы настроить конфиг тайлового ВМ и все?" навели меня на мысль положить на рагульный Луа сильно и навеки... Ведь по сути, применения LUa для администрирования гибридной сети (windaus, *nix, Mac) я не нашел, и потому забил. И тут,
блуждая необьятными просторами нашей вселенной я наткнулся на Qtile  - тайловый ВМ написанный на Python и имеющий конфиг на нем же. И о чудо - питон идеально подходит для системного администрирования. Ну что же засучим рукава и посмотрим на что способен этот зверь...

    Описывать установку Qtile я не буду, потому как данное рукодство можно найти как на сайте  Home Page
    так и на его форуме Forum

    Предположим что установка прошла успешно. Так что нам по сути осталось отредактировать дефолтный конфиг что бы получить сразу немного удобств. Так как у каждого задачи и взгляды свои я попытаюсь сделать универсальный конфиг,  который подойдет большинству для старта. Сосбственно после установки нам необходимо создать папку qtile и скопировать в нее конфиг из примеров что мы и делаем командой


mkdir -p ~/.config/qtile[/code]
далее, скопируем конфиг из папки которую мы стянул с гита для установки
cp build/lib/libqtile/resources/default_config.py ~/.config/qtile/config.py

Далее, я приведу свой конфиг и постараюсь максимально прокомментировать его.
(Те кто не знаком с питоном - пробелы и табуляции необходмо сохранять)

-> cat .config/qtile/config.py

#Импортируем необходимые нам компоненты
from libqtile.manager import Key, Screen, Group, Drag, Click
from libqtile.command import lazy
from libqtile import layout, bar, widget

#Для того что бы сделать конфиг более читабельным, внесем переменные, которые
#позже будем использовать
#(по умолчнию WinKey = mod4,  Alt = mod1)
mod = "mod4"
alt = "mod1"

# Для того что бы указать везде ваш любимый шрифт, не всписывая каждый раз все переменные
#сделаем это через функцию. Которая возвращает нам параметры и размер шрифта который вы указали
def dFont(fs):
    def_font = dict(font='Terminus', fontsize=fs, padding=3,)
    return def_font

#Обозначим хоткеи для смены лайоутов - думаю тут комментарии излишни, если не совсем понятно что и
#зачем, потом просто пробуете и смотрите что меняется
#Layouts Keys
keys = [
    Key(
        [mod], "k",
        lazy.layout.down()
    ),
    Key(
        [mod], "j",
        lazy.layout.up()
    ),
    Key(
        [mod, "control"], "k",
        lazy.layout.shuffle_down()
    ),
    Key(
        [mod, "control"], "j",
        lazy.layout.shuffle_up()
    ),
    Key(
        [mod], "space",
        lazy.layout.next()
    ),
    Key(
        [mod, "shift"], "space",
        lazy.layout.rotate()
    ),
    Key(
        [mod, "shift"], "Return",
        lazy.layout.toggle_split()
    ),
    Key([mod], "h", lazy.to_screen(1)),
    Key([mod], "l", lazy.to_screen(0)),
    Key([alt], "Tab", lazy.nextlayout()),
#Запуск приложений
#Открыть терминал
    Key([mod], "Return", lazy.spawn("urxvt")),
#Открыть браузер
    Key([mod], "w", lazy.spawn("google-chrome")),
#Открыть терминал в котором запустить приложение
    Key([mod], "i", lazy.spawn("urxvt -e ekg2")),

# Application Launcher
# Это утилита dmenu - открывается панелька внизу екрана через которую можно
#быстро запустить нужное вам приложение (необходимо установить dmenu)
    Key(
        [alt], "r",
        lazy.spawn(
            "dmenu_run -b -fn 'Terminus:size=14' -nb '#000000' -nf '#fefefe'")
    ),

# Change the volume if our keyboard has keys
# Если по каким то причинам у вас автоматом не работают клавиши управления зауком на буке
#пропишем их тут
    Key(
        [], "XF86AudioRaiseVolume",
        lazy.spawn("amixer -c 0 -q set Master 2dB+")
    ),
    Key(
        [], "XF86AudioLowerVolume",
        lazy.spawn("amixer -c 0 -q set Master 2dB-")
    ),
    Key(
        [], "XF86AudioMute",
        lazy.spawn("amixer -c 0 -q set Master toggle")
    ),

#Suspend Mode
# если клавиша усыпить не работает пропишем действие на нее (не требует рута - но необходимо установить upower)
    Key(
        [], "XF86Sleep",
        lazy.spawn("dbus-send   --system   --dest=org.freedesktop.UPower   --type=method_call   --print-reply   /org/freedesktop/UPower   org.freedesktop.UPower.Hibernate")
    ),

#Restart Qtile
#Закрыть окно
    Key([mod], "c", lazy.window.kill()),
#Рестартонуть кутиль, при этом все открытые приложения остаются (перечитывается конфиг)
    Key([alt, "control"], "r", lazy.restart()),
]
#Тут проще самому попробовать чем обьяснить.
mouse = [
    Drag([alt], "Button1", lazy.window.set_position_floating(),
         start=lazy.window.get_position()),
    Drag([alt], "Button3", lazy.window.set_size_floating(),
         start=lazy.window.get_size()),
    Click([alt], "Button2", lazy.window.bring_to_front())
]

#Добавим список наших рабочих столов (произвольное количество)
groups = [
    Group("Term"),
    Group("WwW"),
    Group("IM"),
    Group("IDE"),
]
#Переключение между столами по mod+порядковый номер
for index, grp in enumerate(groups):
    keys.extend([
                Key([mod], str(index + 1), lazy.group[grp.name].toscreen()),
                Key([mod, alt], str(index + 1), lazy.window.togroup(grp.name))
                ])
#Лайоуты по умолчанию (откройте 2 окна и поклацайте alt+tab что бы было понятно)
layouts = [
    layout.Max(),
    layout.Stack(stacks=2),
    layout.Tile(ratio=0.25),
]
#Настройка скрина и панели с виджетами, так же можно настроить и на несколько монитров
screens = [
    Screen(
        top=bar.Bar(
            [
            #Вот как раз пользуемся нашим шрифтом по умолчанию
            #в целом я тут постарался перечислить основные парамеры для виджетов
            #так что экспеременитируйте (если редактировать кофиг каким нить ИДЕ то получите автокомплит и.т.д.)
                widget.GroupBox(**dFont(16)),
                widget.CPUGraph(),
                widget.MemoryGraph(),
                widget.WindowName(**dFont(20)),
                widget.Systray(),
                widget.NetGraph(interface='eth1'),
                widget.Clock('%H:%M %a %d/%m', **dFont(20)),
                widget.Volume(foreground="70ff70", **dFont(20)),
                widget.Battery(**dFont(20)),
            ],
            30,
        ),
    ),
]
#ну тут тоже все прозрачно
main = None
follow_mouse_focus = False
cursor_warp = False
floating_layout = layout.Floating()
mouse = ()
#А дальше все ограничено только вашей фантазией, как это все выглядит видно на картинке



Если честно, пока что не могу выделить какие-то заслуги Qtile среди остальных ВМ. Но учитывая мой опыт, результат и затраты труда по его настройке - безусловно он чемпион...
Вот в общем то и все ! Пользуйтесь на здоровье.
Home Page
Forum







четверг, 2 февраля 2012 г.

SMS Gate своими руками

    Много разного железа хранится у каждого хорошего админа в кладовке.  Применения ему нет, а выкинуть какой-то старый но служивший верой и правдой "пень" - не подымается рука.
Вот такие вот древние монстры, зачастую, и становятся  полигоном для экспериментов и настроек всяких гаджетов делающих нашу работу более удобной или же просто добавляют изюминку...
    Речь о такой изюминке и пойдет в этой статье. Потребовалось как то мне делать рассылку  сообщений сотрудникам организации, да что бы каждому приходили нужные только ему данные, да только на его номер... В былые времена с этим прекрасно справлялся почтовый демон, отправляя письма на почту вида +380номер_телефона@провайдер.ком, но времена те прошли... Итого имеем задачу и реализовываем ее:

Необходимо настроить SMS демон который будет:
1.Отправлять сообщения SMS на все операторы
2.Хранить лог отправленных сообщений
3.Вести лог ошибок
4.Быть гибким и не требовательным
5.Работать с базой данных
6.Поддерживать возможность отправки отчетов из 1С (в данном случае 8.2)

    Всем этим требованиям отвечает замечательный продукт gnokii. Пусть вас не смущает его название  и описание поддерживаемых моделей телефонов. Мы его подружим с телефоном Siemens A75 (выпуска начала века) да еще и по СОМ порту, да еще и через такой переходник, что система по идее должна была выдать сообщение о невозможности бытия.... А работать сия чудесная связка будет на оборудование которое как я уже говорил выше - жалко выбросить.
Итого имеем :
Мать - древнее чудо
Память - 2х64= 128 Mb
Видеокарта - PCI S3 Virge (Потребовалось только для установки OS)
Процессор - Pentium III 500 Mhz
Винчестер - WD 10 Gb (Жужжит как шмель - но работает исправно)
В качестве ОС был выбран Ubuntu linux
Linux SmS 3.0.0-15-generic #26-Ubuntu SMP Fri Jan 20  i686 i386 GNU/Linux
 (от Gentoo и FreeBSD пришлось отказаться в виду отсутствия времени на сборку пакетов и системы, а так же места на HDD необходимого для хранения всяких там ненужных нам GCC и прочего..)
Телефон - Siemens A75
Шнур для телефона - хитроумно-самодельный объединяющий в себе кабель передачи данных и зарядное устройство.
Дабы не тратить время и силы на красивую и компактную сборку, "железяка" была собрана в "стендовом" формате и так же инсталирована на стену в серверной. Винт прикрутили на блок питания. Блок питания разместили рядом, удалив лишние провода. Телефон закрепили на материнской плате шлейфом от дисковода. Шнур связали через розетку RJ-45 (чо под рукой было) припаяв парочку резисторов с обратной стороны, благо в сети достаточно схем подключения и разводок. В итого все это чудо выглядит теперь так:


Гламурненько, нестандартно, по своему красиво, но тем не менее - работает стабильно и "кушать не просит"...
Далее - устанавливаем Ubuntu (Я выбрал минимальную инсталяцию). Процесс описывать не стану, так как сложности никакой нет. После установки обновляем систему и устанавливаем следующий перечень пакетов, необходимых нам в работе:
(В виду того что мне влом все время дописывать sudo - я делаю все из под root)
Update :
apt-get update && apt-get upgrade && apt-get dist-upgrade
Install soft:
aptitude install gnokii-cli gnokii-smsd  gnokii-smsd-mysql mysql-server
 этого достаточно для первоначальной настройки нашей системы. Далее нам необходимо отредактировать файл конфигурации gnokii. Учтите тот факт что если вы запускаете службу как демон - то используется файл конфигурации /etc/xdg/gnokii/config а если от пользователя то конфиг должен находиться в ~/.config/gnokii/config
Описывать весь файл я не буду, так как он и так достаточно документирован покажу лишь то, что получилось у меня:

root-> cat /root/.config/gnokii/config 
[global]
model = AT 
connection = serial
initlength = default    
port = /dev/ttyS1
serial_baudrate =9600
smsc_timeout = 100

 Этого достаточно для минимальных запросов.  Значение строк и варианты можно посмотреть в файле /etc/xdg/gnokii/config. Проверим что система видит наше устройство:

gnokii --monitor
Мы должны увидеть что то типа:

Entering monitor mode...
Network: MTS, Україна (255 01)
LAC: 0106 (1050), CellID: 00000089 (152)
RFLevel: 31
Battery: -1
SIM: Used 22, Free 138
Phone: Used 0, Free 0
DC: Used 22, Free 138
EN: Used 0, Free 0
FD: Used 0, Free 0
RC: Used 0, Free 0
CALL0: IDLE
CALL1: IDLE

Если у вас похожие данные - можем уже пробовать отправить СМС:

echo "Some message text"|gnokii --sendsms '+380501234567'

Осталось теперь настроить это все как демон и привязать базу данных.
Создадим базу данных и пользователя для нашего демона:
mysql -uroot -p  
mysql> create database smsd;
Создадим пользователя
mysql> GRANT ALL PRIVILEGES ON smsd.* TO smsduser@"%"

            |IDENTIFIED BY 'smsdpassword' WITH GRANT OPTION;
Выйдем из mysql и проверим что у нас все получилось

root-> mysql -usmsduser -psmsdpassword
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 58
Server version: 5.1.58-1ubuntu1 (Ubuntu)


Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
This software comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to modify and redistribute it under the GPL v2 license


Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| smsd              |
+--------------------+
2 rows in set (0.02 sec)

Далее нам необходимо создать структуру БД. У нас для этого есть уже готовый файл
 /usr/share/doc/gnokii-smsd-mysql/sms.tables.mysql.sql
но его нужно немного изменить. Дело в том, что отправляя смс руками, gnokii  автоматом разбивает длинные сообщения на несколько смс, а вот демон отправляет только одно, отсекая все лишнее. Нас это конечно не устраивает, поэтому перед импортом открываем файл
vim /usr/share/doc/gnokii-smsd-mysql/sms.tables.mysql.sql  (вместо vim можно другой редактор)
находим секцию:
CREATE TABLE outbox 
и меняем в ней параметр
 text varchar(160) default NULL,
на
 text varchar(1000) default NULL,
После чего делаем импорт
root-> mysql -usmsduser -psmsdpassword smsd </usr/share/doc/gnokii-smsd-mysql/sms.tables.mysql.sql
Ну и на последок сделаем наш сервер базы данных доступным по сети, для чего в файле

 /etc/mysql/my.cnf  заменим параметр bind-adress на наш IP

#bind-address           = 127.0.0.1
bind-address            = 10.0.0.100
(Вообще не совсем верный ход, но в данной статье мы не ищем сложных путей)
Осталось только добавить демон в автозагрузку:
создадим файл  /usr/sbin/smsdstart
с таким содержимым:
#!/bin/sh
/usr/sbin/smsd -u smsduser -p smsdpassword -d smsd -c localhost -m mysql -f /var/log/smsdaemon.log
Сделаем файл исполняемым 
chmod +x /usr/sbin/smsdstart
и добавим его в автозапуск
root-> cat /etc/rc.local 
#!/bin/sh -e
# rc.local
#Start SMS daemon script
/usr/sbin/smsdstart
exit 0
Создаем файл лога
touch  /var/log/smsdaemon.log

Перезагружаем систему и убеждаемся что все работает:

root-> ps aux|grep smsd
root       684  0.3  1.9  26412  3676 ?        Sl   Feb01   3:12 /usr/sbin/smsd -u xxxxxxxxx -p xxxxxxxxxxxxx -d xxxxx -c xxxxxxxxx -m mysql -f /var/log/smsdaemon.log
root       918  0.0  0.2   4040   504 pts/2    S+   Feb01   0:00 tail -f /var/log/smsdaemon.log
root      2049  0.0  0.4   4204   772 pts/3    S+   09:41   0:00 grep smsd
root-> ps aux|grep mysql
mysql      583  0.2 10.1 138652 18704 ?        Ssl  Feb01   2:55 /usr/sbin/mysqld
root       684  0.3  1.9  26412  3676 ?        Sl   Feb01   3:12 /usr/sbin/smsd -u xxxxxxxxx -p xxxxxxxxxxxxx -d xxxxx -c xxxxxxxxx -m mysql -f /var/log/smsdaemon.log
root      2051  0.0  0.4   4204   768 pts/3    S+   09:41   0:00 grep mysql

Осталось проверить работоспособность системы. Для того что бы демон отправил смс - необходимо, добавить данные в таблицу outbox:
Синтаксис такой:
insert into outbox (number,text) values ('+380501234567','Super mega demon test');
Пример:
root-> mysql -usmsduser -psmsdpassword
mysql> use smsd;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> insert into outbox (number,text) values ('+380501234567','Super mega demon test');
Query OK, 1 row affected (0.01 sec)

Смотрим отчет в таблице 

mysql> select * from outbox;
+----+---------------+---------------------+---------------------+-----------------------+-------+-----------+-------+---------+------------+-----------+
| id | number        | processed_date      | insertdate          | text                  | phone | processed | error | dreport | not_before | not_after |
+----+---------------+---------------------+---------------------+-----------------------+-------+-----------+-------+---------+------------+-----------+
| 52 | +380501234567 | 2012-02-02 09:54:38 | 2012-02-02 09:54:23 | Super mega demon test |  NULL |         1 |     0 |       0 | 00:00:00   | 23:59:59  |
+----+---------------+---------------------+---------------------+-----------------------+-------+-----------+-------+---------+------------+-----------+
1 row in set (0.00 sec)

root-> tail -f /var/log/smsdaemon.log 
31 січ 2012 21:03:57: Sending to +380501234567 successful.

Все работает! СмС мы получили! Остался последний этап. Необходимо заставить нашу 1С отправлять нам отчеты *(создавать записи в нашей таблице)
Для чего пишем примерно такой вот код 

СоединениеССервером = "Provider=MSDASQL.1; Driver={MySQL ODBC 5.1 Driver}; Server=10.0.0.100; Database=smsd; UID=smsduser; PWD=smsdpassword";
СтрокаВMySQL = "insert into outbox (number,text) values('"+Тел+"','"+ТекстСообщения+"')";
Попытка
Соединение.Execute(СтрокаВMySQL);
ЗаписьЖурналаРегистрации("Отправка СМС",
УровеньЖурналаРегистрации.Информация, , ,
"Сообщение (" + ТекстСообщения + ") отправлено : "+Результат.Пользователь + " на телефон " + Результат.Телефон);
Исключение
ЗаписьЖурналаРегистрации("Отправка СМС",
УровеньЖурналаРегистрации.Ошибка, , ,
"Сообщение не отправлено : "+Результат.Пользователь + " на телефон " + Результат.Телефон + " " + ОписаниеОшибки());
КонецПопытки;

Что конкретно отправлять, какие данные формировать и так далее - каждый разберется уже самостоятельно, так как у каждого свои задачи.
Ну и собственно что бы это все работало с виндауз машинки - необходимо установить ODBC драйвер .

Кроме того можно настроить демон на работу с файлами, добавить выполнение действий на входящие смс и так далее. Возможно я рассмотрю эти пункты в следующих статьях. Отдельная благодарность создателю чудо шнура, моему коллеге  digitec а также оригиналу статьи по настройке gnokii.