-
Crontab и отправка почты
На днях столкнулся с проблемой. На моем ноуте крутится несколько crontab-задач. Хотелось бы видеть, когда сработала каждая из них и если нет, то почему. Какое-то время я выкручивался с помощью логов. Оба канала (stdout и stderr) перехватываются в общий пайп, где каждая строка предваряется текущий датой и записывается в файл. Например:
SHELL=/bin/bash 0 */3 * * * /path/to/command &> >( while read line; do echo "$(date): ${line}"; done >> /Users/ivan/logs/command.log)
В результате и обычный, и ошибочный выхлоп оседают в файле. Выглядит это так:
Tue Jun 22 15:58:02 MSK 2021: warning: Skipping file ... Tue Jun 22 15:58:19 MSK 2021: Completed 0 file(s) with ... Tue Jun 22 15:59:02 MSK 2021: warning: Skipping file /Users/ivan/... Tue Jun 22 15:59:19 MSK 2021: Completed 0 file(s) with ...
Недостаток в том, что логи нужно регулярно проверять. Об этом легко забыть на месяц, а потом выяснится, что задача не работала из-за глупой ошибки.
Тут я вспомнил, что крон умеет отправлять выхлоп задачи на почту. Если задана переменная
MAILTO=<email>
, то на эту почту свалится выхлоп. Это значит, отпадают логи, ведь теперь достаточно проверить почту. Проверять ее можно и с телефона, что в разы удобней.Отправка письма работает за счет утилиты
mail
. В общем виде ей пользуются так:cat something | mail -s 'subject' friend@domain.com
Эта команда отправит письмо на сервер
domain.com
, при этом отправитель будет выглядеть какivan@ivan.local
, то есть имя пользователя и текущего хоста. То же самое можно получить командой:echo `whoami`@`hostname`
Обратите внимание на кавычки – они означают выполнить выражение в новом шелле и подставить результат.
Отправленное письмо никто не получит, что потому что современные сервера отметают письма, где айпи отправителя не совпадает с айпи его домена. Это хорошо, иначе бы мы утонули в спаме. Будем отправлять письма с серверов Гугла. А чтобы
mail
мог подключиться к Гуглу, сделаем три вещи.Первое. В файл
/etc/postfix/main.cf
дописать строки ниже. Делать это нужно подsudo
:relayhost = [smtp.gmail.com]:587 smtp_sasl_auth_enable = yes smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd smtp_sasl_security_options = noanonymous smtp_use_tls = yes smtp_sasl_mechanism_filter = plain
Второе. Создать файл
/etc/postfix/sasl_passwd
и вписать в него:[smtp.gmail.com]:587 username@gmail.com:password
, где
password
— пароль приложения для почты. Сгенерить этот пароль можно на специальной странице Гугла.Замечу, что вместо
gmail.com
может быть ваш домен, если он нацелен на гугловые сервера как в моем случае.Третье — указать
postfix
новые конфиги и перезагрузить его:sudo chmod 600 /etc/postfix/sasl_passwd sudo postmap /etc/postfix/sasl_passwd sudo launchctl stop org.postfix.master sudo launchctl start org.postfix.master
Все. Пробуем отправить письмо. Сообщим в нем содержимое домашней папки:
ls -l | mail -s 'my home dir' ivan@grishaev.me
Мне пришло с первого раза. Plain text, красота.
Так вот, теперь когда почта работает, настроим крон. Открываем его командой
crontab -e
и пишем сверху:MAILTO=<ваша@почта>
Кроме того, в конец каждой команды добавляем эхо, например:
0 */3 * * * cd /some/path && command --foo 42 && echo OK
Зачем нужно эхо? Оказалось, что крон не отправляет письмо, если выхлоп задачи пуст. А поскольку я всегда хочу знать о запуске задачи, то делаю вывод не пустым. Вместо
echo OK
можно вывести текущую дату с помощью&& date
.В результате мы получим письмо, где тема — команда задачи, а тело — ее выхлоп. Работает в том числе и для задач, которые не сработали из-за ошибки.
Я уж не говорю о том, что с помощью
mail
можно быстро что-то скидывать себе на почту, организовать какие-то заметки и прочее. Что самое прекрасное — нет интерфейса, все простое и открытое, работает везде. Чудо.В следующий раз расскажу, что именно я ставлю на крон, там тоже интересные вещи.
-
И ещё немного книг
Выкладываю ещё несколько прочитанных книжек. Полную подборку см. на книжной полке.
Чернобыль. История катастрофы
Хиггинботам АдамПолная история чернобыльских событий. Начинается задолго до взрыва, охватывает становление Припяти и ранние опыты с атомной энергией в СССР. Подробно описаны причины, которые привели к взрыву, в том числе организационные. Центральные персонажи показаны правдиво и без тех прикрас, что были в сериале HBO. Книга заканчивается развалом СССР и эпилогом. Рекомендую к прочтению.
Digital минимализм. Как навести порядок в цифровой среде
Рыжина АнастасияКнига о том, как навести порядок в файлах: на локальном компе и в облачных хранилищах. Довольно занятно, но затянуто. Проблема в том, что материал тянет на хорошую статью, но никак не на книгу. Отсюда дешёвые способы выйти на объём: мудрые цитаты на разворот, письма читателей и прочий балласт. Но пробежаться стоит.
Думай как математик. Как решать любые задачи быстрее и эффективнее
Барбара ОаклиАвтор — женщина-учёный, служила в армии США, преподавала в университете. В книге она описывает приемы эффективного обучения. Например, заниматься понемногу, но регулярно; не подчеркивать в книгах; мысленно пересказывать материал. Полезно, но затянуто. Я бы сократил книгу на треть.
Структуры данных и алгоритмы в Java Лафоре Роберт
Лафоре РобертПрекрасная книга об алгоритмах. Столь понятного изложения я уже давно не встречал. Все алгоритмы показаны картинками и схемами; к каждому прилагается программа с интерфейсом для визуализации. Первая часть книги посвящена сортировке, вторая — деревьям. Все примеры на Java версии 1.3. Пусть это вас не пугает: никаких классов, всё на примитивах и массивах. Горячо рекомендую книгу всем, кто хочет разобраться с коллекциями и алгоритмами.
Уступите место драме. Как писать интересно даже на скучные темы
Сарычева ЛюдмилаКнига о драматургии Люды Сарычевой, соавтора "Пиши, сокращай". Не думайте, что драматургия — это обязательно Шекспир и все умирают. Речь о том, как сделать текст интересней с помощью персонажей и конфликтов, как обострять акценты и чередовать ритм. Прочитал половину: начало интересное и пригодится всем, а дальше уже только для специалистов в теме.
Ходячий замок
Джонс Диана УиннСмотрел этот мульт три раза и вот добрался до книги. Ощущения смешанные: сюжеты расходится, характеры персонажей разнятся. Книга местами затянута и её ритм скачет. Я бы сказал, что мультфильм лучше книги, причём не в плане эффектов, а потому что несёт больше чувств. Но прочитать стоит.
Искусство войны
Сунь-ЦзыТот самый трактат о войне, написанный две с половиной тысячи лет назад. Оригинал довольно короткий, буквально дюжина керамических табличек. Поэтому современные издания напичканы комментариями толкователей всех мастей. Это весьма раздражает: после каждой фразы оригинала следуют пять абзацев комментариев. К самому трактату претензий нет: он точен, ясен, в нём нет лишних деталей, он несет много пищи для размышления. Удивительно, что человек, который занимался войной, так много пишет о милосердии и заботе о людях.
-
Introducing Farseer: the JSON RPC server, the client and utilities
(This is a copy of the readme file from the repository.)
Farseer is a set of modules for JSON RPC. It includes a transport-independent handler, Ring HTTP handler, Jetty server, HTTP client, local stub, documentation, and more.
- What and Why is JSON RPC?
- The Structure of this Project
- RPC Handler
- Ring HTTP Handler
- Jetty Server
- HTTP Stub
- HTTP Client
- Documentation Builder
- Ideas & Further Development
What and Why is JSON RPC?
Briefly, JSON RPC is a protocol based on HTTP & JSON. When calling the server, you specify the method (procedure) name and its parameters. The parameters could be either a map or a vector. The server returns a JSON response with the
result
orerror
fields. For example:Request:
{"jsonrpc": "2.0", "method": "sum", "params": [1, 2], "id": 3}
Response:
{"jsonrpc": "2.0", "result": 3, "id": 3}
Pay attention: the protocol depends on neither HTTP method, nor query params, nor HTTP headers and so on. Although looking a bit primitive, this schema eventually appears to be robust, scalable and reliable.
-
Сага о DRY и зависимостях
Предположим, в вашем проекте два модуля:
project.foo
иproject.bar
. В первый из них вы добавили служебную функцию, например поиск элемента по предикату. Через некоторое время то же самое понадобилось во втором модуле. Как вы поступите?Варианты:
- Вынесу функцию в третий модуль
project.utils
и подключу его кfoo
иbar
. - Скопирую функцию во второй модуль.
Конечно, вы и так знаете, что правильный способ — первый. DRY (Don’t Repeat Yourself), не дублируй код. Держи одну точку входа, чтобы в случае ошибки править в одном месте. Копирование — наш враг и все такое. Я тоже тоже так думал раньше, и вот, в тридцать пять лет, поменял мнение.
- Вынесу функцию в третий модуль
-
Clojure Zippers
- Part 1. The Basics of Navigation
- Part 2. Automatic navigation
- Part 3. XML zippers
- Part 4. XML search
- Part 5. Editing
- Part 6. Virtual Trees. Currency Exchange
- Part 7. Breadth-First Traversal. Improved Currency Exchange
- Part 8. Summary
Part 1. The Basics of Navigation
In this article, we will discuss zippers in the Clojure language. These are an unusual way to work with collections. Using a zipper, you can traverse a data structure arbitrarily and modify its content as well as search in it. A zipper is a powerful abstraction that pays off over time. However, it is not as straightforward as regular tools and requires training to deal with.
Let’s talk about a zipper in simple terms. It is a wrapper that offers a variety of data manipulations. Let’s list the main ones:
- moving vertically: down to children or up to a parent;
- moving horizontally: left or right among children;
- traversal of the entire data structure;
- adding, editing and deleting nodes.
-
Ссылки на выходные (выпуск 34)
Советую посвятить выходные новому изданию “Кинжал”. Ребята пишут небольшие заметки о работе и жизни. Получается супер. Каждая заметка — острая и хлесткая, как настоящий кинжал. Никакой воды, только по сути. Эти вещи вы читали у других и у меня, но в “Кинжале” написано лучше.
То, что зацепило:
И так далее, на сайте еще.
А вот Максим Ильяхов (он там редачит) рассказывает об издании.
-
Configuration in Clojure
Clojure in Production
- Chapter 1. Web development
- Chapter 2. Clojure.spec
- Chapter 3. Exceptions
- Chapter 4. Mutability
- Chapter 5. Configuration
- Chapter 6. Systems in Clojure
- Chapter 7. Tests
In This Chapter
- Configuration
- Formulation of the Problem
- Semantics
- Configuration Cycle
- Config Errors
- Configuration Loader
- More on Environment Variables
- Config in the Environment
- Disadvantages of the Environment
- Environment Variables in Clojure
- Simple configuration manager
- Reading the Environment from Config
- Overview of Formats
- Industrial Solutions
- Summary
Configuration
In this chapter, we will discuss how to make a Clojure project easy to configure. We’ll take a look at the basics of config: file formats, environment variables, libraries, and their pros and cons.
Formulation of the Problem
In materials on Clojure, there are such examples:
(def server (jetty/run-jetty app {:port 8080})) (def db {:dbtype "postgres" :dbname "test" :user "ivan" :password "test"})
These are the server on port 8080 and the parameters for connecting to the database. The examples are useful because you can execute them in the REPL and check their result: open a page in a browser or perform a SQL query.
In practice, we should write code so that it does not carry concrete numbers and strings. Explicitly setting a port number to a server is considered bad practice. That is fine for documentation and examples, but not for the production launch.
Port 8080 and other combinations of zeros and eights are popular with programmers. There is a good chance that the port is occupied by another server. This happens when instead of running one service, you start a bunch of them at once during development or testing.
The code written by a programmer goes through several stages. These stages may differ between companies, but in general, they are development, testing, staging/pre-production, and production.
At each stage, the application runs alongside other projects. The assumption that port 8080 is free anytime is fanciful. In developer slang, the situation is called “hardcode” or “nailed down.” If there are nailed-down values in the code, they introduce problems into its life cycle. You cannot run two projects in parallel which declare port 8080 in their code.
The application does not need to know the server port – information about this comes from the outside. In a simple case, this source is the config file. The program reads the port from it and starts the server exactly as it needs to do on a specific machine.
In more complex scenarios, the file is not compiled by a person but a special program – a configuration manager. The manager stores information about network topology, machine addresses, and database access parameters. On request, it generate a config file for a specific machine or network segment.
The process of passing parameters to an application and accepting them is called configuration. This step in software development deserves close attention. When it is done well, the project easily goes through all the stages of production.
-
Можно ударить по голове
Недавно я употребил в блоге фразу: если не выстрелит, ей можно ударить по голове (речь о втором издании книги). Это отсылка к фильму Snatch, в русском переводе “Большой куш”. Вспомнил, как мы с приятелем будучи подростками смотрели гоблинский перевод и ржали над матами. А ещё вспомнил, что даже тогда заметил одну деталь, связанную с этой фразой.
Напомню, её несколько раз произносит торговец оружием Борис. Он толкает покупателям откровенный хлам. Покупатель взвешивает оружие и замечает — что-то тяжеловато. На что Борис отвечает: тяжесть — это надёжность. Если не выстрелит, им можно ударить по голове.
Фраза звучит несколько раз, и очевидно, в какой-то момент она должна сыграть. Поскольку мы в комедии, нелепый тезис должен сработать при нелепых обстоятельствах. Другими словами, повторяя некую фразу, режиссер подводит зрителя к ситуации. И тут нас ждёт разочарование — в случае “не выстрелит” режиссер не уделил шутке внимания.
Томми, партнер главного героя, покупает нерабочий пистолет. Позже он испытывает его из окна машины, и оружие дает осечку. Но в момент, когда Турецкого готовы убить, Томми наставляет пистолет на бандитов и тем спасает Турецкого. Таким образом выполняется только первая часть шутки — не выстрелит.
Ещё подростком я понял, что надо было обыграть фразу по-другому. Во-первых, когда Турецкий предлагает выстрелить из машины, Томми должен был отказаться. Якобы потому, что Борис — надёжный продавец как и его товар, поэтому сомневаться нет смысла. На самом деле Томми боится оружия, и это только бы усилило ожидание шутки.
Когда на Турецкого нападают бандиты, один из них душит его. Томми пытается выстрелить, но пистолет не работает. В глазах Турецкого ужас — пропала последняя надежда, ведь на физические способности Томми рассчитывать не приходится. Томми мечется, его взгляд падает на нерабочий пистолет. Он вспоминает напутствие продавца, берет пистолет за ствол и бьет бандита по голове. Тот сползает с Турецкого. Оба героя переводят дух, молча смотрят на оружие и кивают. В их глазах проскальзывает “действительно, им можно ударить по голове”.
Так сбывается нелепое пророчество. В этом варианте раскрыты обе части шутки, и согласитесь, это было бы смешнее (в рамках криминальной комедии). Конечно, на словах звучит слегка коряво, но режиссёр на то и нужен, чтобы всё это обыграть камерой, мимикой, диалогами.
Морали нет, просто наблюдение. Уже давно замечаю за собой, что после фильма обдумываю отдельные сцены, чтобы найти более удачные повороты сюжета, диалоги или черты персонажей. Эта заметка — попытка зафиксировать одну из таких идей.
-
Переназначение клавиш на Маке
В этой статье я бы хотел поговорить об изменении клавиш на клавиатуре. Сперва это была короткая заметка, но со временем текст вырос во что-то большее. Оказалось, есть что сказать по теме.
Вообще, я не стремлюсь менять клавиши и затачивать программы под себя. Разработчики предлагают удобные схемы, и в целом удобно, когда вы работаете на стандартных настройках. Всё же, годы за клавиатурой подталкивают к некоторым изменениям.
Главный довод в пользу изменения клавиш — физиология. У людей разная форма кистей и длина пальцев. Невозможно выпустить клавиатуру, которая подошла бы всем людям. Именно физиология и чуткое внимание к ощущениям подсказывают, что менять что-то нужно, иначе — боль в суставах.
Одно время я увлекался эргономичными клавиатурами, но быстро разочаровался в них. За огромные деньги мы получим поделие Франкенштейна: огромных размеров, тяжелое, неудобное. Такая клавиатура полностью меняет рабочее пространство, заставляет кое-что купить в довесок. Её не возьмешь в командировку или на дачу, словом — нет.
Типичные пациенты:
На последней картинке – Microsoft Sculpt. Я пользовался ей полгода, но страшно заболела левая рука.
-
Что не так
Один из самых дурацких вопросов — “что не так с X”. Примеры:
- Мы в редакции не используем букву ё.
-
Что не так с ё?
- Мы перешли с Node.js на Python.
-
Что не так с Нодой?
- Новый ролик я монтировал в Final Cut, а не Premiere.
- Что не так с Премьером?
Беда вот в чём. Ни одно из утверждений не говорит о том, что с буквой ё, программой или языком что-то не так. От них отказались по каким-то причинам, а с самим предметом всё в порядке. Поэтому вопрос задан неправильно — следовало спросить, почему вы решили; почему отказались; что вынудило и так далее.
Но собеседник переложил работу на меня. Я понимаю, что он имел в виду, но тогда мой ответ звучит слабо. С буквой ё все в порядке, просто мы…, программа хорошая, но я… Получается ерунда.
Заметил, что подобный вопросы задают тролли, которым нужна подобная интонация. Либо человек, которым движет вера. Что бы вы ни сказали, он будет гнуть свою линию. Отсюда эта лёгкая дерзость: во фразе “что не так с X” уже слышится претензия.
Подобные вещи я либо игнорирую, либо прошу задать вопрос правильно. Что ты имеешь в виду? Я не говорил, что с X что-то не так. Объясни, чего хочешь.
Кидайте эту заметку тем, кто злоупотребляет “что не так с X”.
См. также Whataboutism.