VersionEye goes Open Source

VersionEye – a very useful service that I use for outdated software tracking in projects I’m working on. It sends me notifications whenever any third-party library is outdated or vulnerability detected.

From now it is Open Source. If you wish – you can run your very own copy inside you company network or continue using services. Robert Reiz explains why they moved from Black Box to Open Source model with MIT license in VersionEye goes open source blog post.

So, keep your software up to date!

First time with Logstash Elasticsearch and Kibana

On February 2th my colleague Simonas Šerlinskas presented topic “Logs” on VilniusPHP event in interesting perspective. In 30 minutes he presented the way to grab and analyze huge amount of logs with nice graphical visualization using logstash, elasticsearch and kibana.

I’ve had no idea that I will need that trio next day during some logs analysis. It’s nice to have such powerful tools installed, configured and running in matter of hours, ready to accept and analyze data. Of course – most of the settings where default, no high availability, almost zero security (in-house, closed VM), but results was worth spent time. logstash + elasticsearch + kibana just did the job and then where just wiped.

Wish to have something like that many years ago… but.

No space left on device: Small files and inodes

I’ve run out of “free space” on building, testing and staging servers few times in last year with relatively small projects based on Symfony 2 or Zend Framework 2.

Used frameworks are rather small:

  • Symfony (2.4): 6450 files, 1283 folders, 46788608 bytes (apparent size 29894665)
  • Zend Framework (2.2): 2421 files, 427 folders, 17498112 bytes (apparent size 10912260)

So, framework or project files are not the issue, even if you build, test and deploy many times per day without removing previous releases (deployment process issue, fixed first). I’m talking in file size context.

So when you run out of free space – you login into server and type:

df -h

and see that you have half of partition empty (sometimes more), but when you try to create a new file you get: “No space left on device”.

But why? But how?

In my case it was inode count. I’ve run out of inodes on my partition. To see inode usage type:

df -i

So, inode (index node) is a data structure used to represent a filesystem object. Read more on Wikipedia or try to use search engines to find more info about inode.

At trouble making servers I’ve used default settings for my filesystems.

For example: if you have Ubuntu 13.10 and 4GB partition formatted with ext3 filesystem you will have 262144 inodes.
I’ve tried to copy Zend Framework 2 on that partition: 92 good copies, 1 corrupted copy, 2.2 GB free and out of inodes – waste of disk space. With Symfony 2 I’ve got 33 copies and out of inodes.

How to solve this issue? Buy bigger drive or increase inode count when you create filesystem on partition.

I’ll try to calculate optimal inode count for 4Gb partition with ext3 filesystem for both frameworks with maximal copies count. It might be a synthetic example, but if you automate builds of many projects with similar file count and file size ratio – this might help.

Partition size is about 3781115904 bytes, so we can copy ~80 Symfony 2 copies or ~216 copies of Zend Framework 2. Symfony 2 will require about 618640 inodes and Zend Framework 2 about 615168 inodes (inode per file or directory). Lets create ext3 filesystem on 4GB partition with 620000 inodes. Command for example:

mkfs.ext3 -N 620000 /dev/sdb1

I’ve tried to copy Zend Framework 2 on that partition: 216 good copies, with Symfony 2 I’ve got 79 copies – more than twice bigger.

Another way to calculate inodes count for partition: average file size in your project. Zend framework 2 7227 bytes, Symfony 2 7254 bytes, so on 3781115904 bytes partition we might have up to 522254 files (with avg.: 7240 bytes per file).

Conclusion: default filesystem settings not always the best choice for build, testing or staging servers. Look at your project or projects you will place on your servers, do some calculations – you might get better disk space usage for same price. Don’t forget, that you might need to place Composer cache somewhere on your build server – PHP projects/frameworks/libraries have quite big amount of smaller files in our times (in development versions even more) – this knowledge might be handy.

This calculations might not be suitable for production servers – user uploaded content might change average file size and your inode count might be a penalty. I never tested is there any performance penalties (or other drawbacks) if you increase inodes count.

Don’t forget that this rules apply only for filesystems with inodes, like ext2, ext3. Ext4 might have other rules (depends on settings). There are filesystems without inodes too.

Front-end package managers

What I’ve missed in 2013: Front-end package manager.

I just hate to go to vendor websites, downloading zip/tgz/tar.bz2 files, unpacking them, coping files, placing in some folders, and so on, and so on. Every time you need to install new front-end library or framework – you do the same. Every time you need to update something – you do the same.

So, the short list of Front-end package managers:

Useful quick comparison of them done by Wil Moore III at his GitHub account: Front-End Package Manager Comparison.

All looks great with small exceptions: packages support from vendors. Not all packages are present in all managers or there are old versions, not all vendors want to support package managers.

I hope everything will change in matter of months or a year.

Composer/Satis and GitHub Rate Limits

Composer/Satis and GitHub Rate Limits – hit this issue today. 60 requests per hours is not so match when you use Composer to build a project few times or you try to build local package repo with Satis with empty composer cache.

Actually, I wonder, why I didn’t hit rate limits (introduced in October 2012) earlier with Continues Integration building project few times per hour. Possibly Composer cache saved the day (TTL of cache is about 6 months by default). But I see many request (or issues) over Internet about this issue… and spent couple of hours solving it today to achieve my goals.

One of the best solutions I’ve found: Alister Bulman – Avoiding Composer Being Rate-limited by Github and it works perfectly with Composer and failed with Satis (at least for now).

After few “var_dump” of Satis and Composer I’ve found that Composer reads “global” configuration file from “COMPOSER_HOME” directory (next time do some RTFM: COMPOSER_HOME/config.json) and merges with local project settings.

So, if you place your GitHub OAuth key, created by Alister Bulman instructions, into COMPOSER_HOME/config.json file – you won’t need to place it anywhere else until you hit 5000 limit.

Example of COMPOSER_HOME/config.json:

"config": {
"github-oauth": {
"": "<your GitHub OAuth Key>"

From now my Composer and Satis works fine. Might help if you use Continues Integration servers.

More about COMPOSER_HOME directory.

Some obvious things learned hard way.

Zend Framework 2 Cache Storage Factories

If you are making an application with Zend Framework 2 (version 2.2) and you need some data Caching – you will find good examples on Zend\Cache usage, but not much about cache initialization or how to store cache configuration.

If you are able to use Google or Bing (or any other modern search engine) – you will find many example how to initiate cache using closures or your own factories or any other fun ideas… but!

ZF2 provides two great ways to store cache configuration for cache storage adapters and initialization of Cache services trough ServiceLocator:

  1. Zend\Cache\Service\StorageCacheFactory
  2. Zend\Cache\Service\StorageCacheAbstractServiceFactory

Both of them are just a Service factories that could be used easily trough ServiceLocator. Storage adapter settings could be set in any configuration file you like (from any module.config.php to config/autoload/any.local.php).

The last one, StorageCacheAbstractServiceFactory, is enabled by default in ZendSkeletonApplication.

If you are using one cache adapter trough all you application, you can just do three things:

1) Add Service with desired name for Cache service which would be initialized by Zend\Cache\Service\StorageCacheFactory somewhere in you Application or Module config file:

return array(
'service_manager' => array(
'factories' => array(
'Application\Cache' =>

2) Add Cache Adapter configuration in you configuration files under the key ‘cache’:

return array(
'cache' => array(
'adapter' => array(
'name' => 'filesystem'
'options' => array(
'cache_dir' => 'data/cache/',
// other options

3) Use Cache adapter trough Service Locator:

// example from controller
* @var $cache \Zend\Cache\Storage\StorageInterface
$cache = $this->getServiceLocator()->get('Application\Cache');

If you need many different cache adapter with different settings – use StorageCacheAbstractServiceFactory:

1) Add Abstract Service Factory somewhere in you Application or Module config:

return array(
'service_manager' => array(
'abstract_factories' => array(

2) Add Cache Adapters configuration in you configuration files under the key ‘caches’ by associative array “ServiceName => Settings array”:

return array(
'caches' => array(
'CacheServiceOne' => array(
'adapter' => array(
'name' => 'filesystem'
'options' => array(
'cache_dir' => 'data/cache_dir_one/',
// other options
'CacheServiceTwo' => array(
'adapter' => array(
'name' => 'filesystem'
'options' => array(
'cache_dir' => 'data/cache_dir_two/',
// other options
// more cache adapters settings

3) Use Cache adapters trough Service Locator in your Application:

// example from controller
* @var $cacheOne \Zend\Cache\Storage\StorageInterface
$cacheOne = $this->getServiceLocator()->get('CacheServiceOne');
// ...
* @var $cacheTwo \Zend\Cache\Storage\StorageInterface
$cacheTwo = $this->getServiceLocator()->get('CacheServiceTwo');

That all: no magic, everything configurable and no closures – only factories.

PHP Conf 2009 Kaunas

Да, да я пишу о PHP Conf 2009 Kaunas, который произошёл 2 месяца назад, ещё 21 апреля 2009 года. Как-то туго у меня со свободным временем и всё что осталось свободным от работы ты тратишь на семью и отдых.

О том, что организуется PHP конференция я узнал один из первых, так как меня пригласили туда организаторы и не пассивным слушателем. К сожаления конференция проходила в рабочий день, что было немного не удобно с моим напряжённым графиком. Но свободный день на работе мне дали очень легко — поэтому я согласился в ней участвовать.

Организаторы были в этом году теже, что и в прошлом: InfoShow и «Net Frequency». Всё происходило в центре дистанционного обучения Каунасского технологического университета.

Тема у меня благодатная: «PHP+MySQL проекты с огромной посещаемостью», информация по ней много в сети, и я сделал просто выборку по теме и подкрепил её своими жизненными примерами. Презентацию я сделал на ура за несколько часов в одно из воскресений после прогулок по магазинам с супругой. Потом потратил пару часов на доработку.

Поездка в Каунас прошла очень гладко — 100 км на автобусе проехать очень просто и не долго по автостраде. Музыка в плеере, 3G интернет в мобильном, пара звонков, включая организаторов: попросили выслать им презентацию заранее, что-бы перенесли её в нужный компьютер — переслал её прямо в пути через Gmail клиент в Nokia. Тут всё прошло без проблем.

Сама конференция в этом году прошла очень и очень интересно и я бы сказал на довольно высоком уровне.

Во первых, все докладчики подобрали очень интересные темы:
Rytis Lukoševičius — «Как стать лучшим программистом»
Очень понравилась идея «имени-бренда», очень правильные идеи относительно того что работа должна нравиться. Это не новость, но тема в наши дни я думаю очень актуальная для многих, особенно начинающих PHP программистов.

Rimantas Liubertas — «Дистрибутивные системы контроля версий: git, mercurial, bazaar»
Актуальная тема для многих — такие системы как git или bazaar становятся всё популярней и востребованней среди разработчиков. Беглое ознакомление с ними многим может помочь в дальнейшем при их изучении, да и за всеми новостями не всегда успееш.

Paulius Jačionis — «Как справиться с огромными потоками пользователей»
Человек представил именно свою визию (точнее команды, которая работает над проектом, как бороться с нагрузкой, которая образуется при больших потоках пользователей имея маленький парк машин. Очень рад, что я не один здесь и решения которые принимаю я совпадают с теми, что принимают они.

Edvinas Tamošiūnas — «Как новичку влиться в команду, быстро и эффективно»
Это была довольная весёлая презентация с серьёзными и не очень советами. Кто первый раз попадал в такую ситуацию — то они полезны, кто не раз менял работу — то наверняка уже имеет свою тактику.

Giedrius Kriščiukaitis — «За качество и эффективность»
Не ожидал такой открытой презентации о том, что происходит внутри отдельно взятой компании, методах и технологиях. Местами казалось, что работать в «Net Frequency» для меня было-бы вызовом.

Во вторых аудитория в зале задавала очень правильные и конкретные вопросы, а также делилась своим опытом, советами и замечаниями.

Понравилось замечания в адрес моей презентации от Giedrius Kriščiukaitis, что в ней не упомянуто ни одного способа как проверить максимальную нагрузку на разрабатываемом проекте, ни показаны числа. К сожаления у меня нет этих чисел и способов проверить — я работаю с проектом, который уже до меня разместили на нескольких серверах с распределением нагрузки и провести тесты на живом проекте не представляется возможным — ни сайт есть желание положить, ни канал с такой пропускной мощностью, так что многое делается «по приборам» и внутреннему чутью команды. Я покупать копию по «желеу» для этих нужд никто не будет.

Что не понравилось, так то, что Tomas Liubinas и Vladas Diržys не представили свои темы: «OXID eShop Community Edition» и «Не изобретай велосипед, используй framework. Плюсы Zend Framework». Я очень ждал этих презентаций.

На after-party я не пошёл, так как предстояла дорога домой, дома ждала любящая супруга и вкусный ужин. Да и не любитель я пить пиво вечером в другом городе, если потом ехать куда-то надо.