Icinga Web, Uncaught AgaviLoggingException thrown, Cannot open file “log/debug.log”

When trying to get Icinga Web to work, you may run into issue with the log directory not being writable

Uncaught AgaviLoggingException thrown
Cannot open file "log/debug-2014-01-28.log", 
please check permissions on file or directory.

It doesn’t appear to be referencing the core directory, or any other relative directory, so the easiest fix is to create an absolute path to where you want to log files to be written to.

vi /usr/local/icinga-web/app/config/logging.xml

Then update the directories so that they point somewhere valid as below

Agavi appender to dump into filesystem
* Log files are rotated in a 7 day (AgaviRotatingFileLoggerAppender default) cycle
* Use 'cycle' parameter to alter the cycle.
<appender name="UniversalLogfileAppender" class="AgaviRotatingFileLoggerAppender" layout="ApacheStyle">
<ae:parameter name="dir">/var/icinga-log/</ae:parameter>
<ae:parameter name="prefix">icinga-web-</ae:parameter>

<appender name="DebugLogfileAppender" class="AgaviRotatingFileLoggerAppender" layout="ApacheStyle">
<ae:parameter name="dir">/var/icinga-log/</ae:parameter>
<ae:parameter name="prefix">debug-</ae:parameter>

Icinga Web, Set correct write permissions for directory “/usr/local/icinga-web/app/cache”

If you have followed the Icinga install procedure through as per the installation documentation, and are having difficulty getting Icinga Web to install, you may eventually get an Agavi error saying that the cache directory is not writable (if you find the PHP errors)


Failed to write cache file "/usr/local/icinga-web/app/cache/config/config_handlers.xml_production__d98552ff67d2d50d8def4e3ddb970ba8e8e151fc.php" 
generated from configuration file "/usr/local/icinga-web/app/config/config_handlers.xml".

Please make sure you have set correct write permissions for directory "/usr/local/icinga-web/app/cache".

For some bizarre reason this still occurs if you change the ownership and permissions of the directory.

The workaround I found involves changing the cache path to somewhere else on the filesystem outside of the Icinga application directory.

vi /usr/local/icinga-web/app/config.php

Then change the cache directory to be somewhere outside of the application directory (make sure the directory exists and has the correct writeable permissions for Apache)

//AgaviConfig::set('core.cache_dir', '/usr/local/icinga-web/app/cache');
AgaviConfig::set('core.cache_dir', '/var/icinga-web');

Add URL query parameters to links using view helper in Zend Framework 2

There are 2 ways to add query parameters using the URL view helper in Zend Framework 2, either using Segment route placeholders, or adding them as normal query parameters (e.g. url?id=1&name=barney)

Which one you need to use depends on what route the view helper is being used on; since all URL’s in Zend Framework 2 need to be route-aware (even if you’re mimicking ZF1 routing) it depends whether the route you’ve specific is ‘aware’ of the parameters.

Segment route parameters

If you have setup a route with segment placeholder for the parameters you need to use, you will be able to specify them


// Output the URL in the view
echo $this->url('somewhere',
    array('controller' => 'company', 
          'id' => $company->id

// Access the corresponding parameter in a controller

Normal query parameters

Sports Points on DailyProgrammer

Here is my solution to the Sports Points code test on r/dailyprogrammer

You must write code that verifies the awarded points for a fictional sport are valid. This sport is a simplification of American Football scoring rules. This means that the score values must be any logical combination of the following four rewards:

  • 6 points for a “touch-down”
  • 3 points for a “field-goal”
  • 1 point for an “extra-point”; can only be rewarded after a touch-down. Mutually-exclusive with “two-point conversion”
  • 2 points for a “two-point conversion”; can only be rewarded after a touch-down. Mutually-exclusive with “extra-point”

A valid score could be 7, which can come from a single “touch-down” and then an “extra-point”. Another example could be 6, from either a single “touch-down” or two “field-goals”. 4 is not a valid score, since it cannot be formed by any well-combined rewards.

Formal Inputs & Outputs

Input Description

Input will consist of a single positive integer given on standard console input.

Output Description

Print “Valid Score” or “Invalid Score” based on the respective validity of the given score.

Sample Inputs & Outputs

Sample Input 1

Sample Output 1
Valid Score

Sample Input 2

Sample Output 2
Invalid Score


Mock a JSON HTTP API response in a PHPUnit unit test for Zend Framework 2

In order to mock an API in a unit test, you need to be able to mock the response that comes back from the API request. Therefore you need to specify in the test what JSON (for example) would come back from the HTTP client.

To do this in Zend Framework 2, you need to mock the Zend\Http\Client so that it always returns a mock response, and have the mock Zend\Http\Response always return the JSON content that you want.

Install ZeroMQ on Mac with PHP PECL extension

Getting ZeroMQ working on a Mac looks like a pain if you try to compile, but there’s a much easier way to get it up and running, with just a few brew and PECL commands.

I’ve been wary of Homebrew for a while, as there were lots of issues with Macports in the past, but I’ve found it’s a lot easier than trying to compile various things yourself in OS X (I tried to compile 0MQ, which took a while and ended up broken anyway)


Install Homebrew and ZeroMQ

Grab a copy of Homebrew then run the following command

brew install zeromq

Then once this is installed, install the PECL extension for PHP

Enable ZeroMQ support for PHP

sudo pear channel-discover pear.zero.mq
sudo pecl install pear.zero.mq/zmq-beta


If you have more than one PHP binary on your computer (such as if you are using Zend Server on OS X, which means you will have the default PHP binary and the Zend PHP binary) then even if 0MQ looks like it is enabled using phpinfo() you may still get the following error from Composer:

– Installation request for react/zmq dev-master -> satisfiable by react/zmq[dev-master].
– react/zmq dev-master requires ext-zmq * -> the requested PHP extension zmq is missing from your system.

This is because Composer uses the PHP-CLI binary to both check and install things, meaning that unless it’s enabled for the binary it’s looking at, it won’t install, even if your web server has it enabled.

You just need to add (even temporarily) the correct PHP binary to the shell path:

export PATH=/usr/local/zend/bin:$PATH

(change depending on where your other binary is)

Then run composer.phar install again and it should work.

Create diff patch from Composer /vendor to apply to Git repository

If you’ve accidentally made changes to a package in the /vendor directory of your project, you’ll need to apply these same changes to the Git repository that the package comes from (or fork it and patch it, etc.) before Composer overwrites the updates.

The easiest way to do this is to create a diff patch which you can then apply to the package repository. You need to make sure it’s relative to the package root for when you apply the patch.

cd vendor/PackageName/
git diff > changes.diff

Then go into the Git repository (or fork) of the package and apply the patch.

cd RepositoryName/
git apply --ignore-space-change --ignore-whitespace changes.diff

Late Static Binding namespace resolution in PHP

If you try to get the namespace of the child class that you are in using the __NAMESPACE__ keyword, you will have the same problem that you do using functions like get_class() in that you will get the namespace (or class) where the current method you are calling is defined.

$namespace = __NAMESPACE__;
$class = get_class();

You can use get_called_class() to resolve this for Late Static Binding with classes, but no such function exists for namespaces that I can find.

$class = get_called_class();

However you can work this out by using the fully-qualified class name, and deducing the namespace from that; if you get the Late Static Binding class name, then you can get the Late Static Binding namespace.

Capistrano website deployment with PHP Composer

Composer is great for handling PHP dependencies, and Capistrano is great for automated deployment, so wouldn’t it be great if you could use them together?

To do this, all you need to do is update your recipe with the following task, then add a hook to make it run when the recipe is used.

To add the hook, make sure that Composer is triggered after finalize_update (which means it will happen before symlink)

after "deploy:finalize_update", "deploy:composer_install"

Then for the task, the simplest solution is to call Composer from the CLI using the Ruby run command.

task :composer_install do
    run "php /var/www/composer.phar install --working-dir #{latest_release}"

This assumes that you have a composer.phar located outside of your repository; you can add it into your repository if you cannot place it anywhere else on the server.

If you need to download composer there are official instructions, or if you are having issues there is troubleshooting information available also.

Disable auto-correct for oh-my-zsh when using Chef Knife (or other commands)

oh-my-zsh is great, but certain commands it doesn’t like, for example the Knife CLI tool for Chef. Luckily it is possible to disable auto-correct as required.

sudo vim ~/.zshrc

To disable just auto-correction for Knife, add the following line somewhere in the configuration

nocorrect knife

To disable all auto-correct (which I prefer personally) add the following line somewhere in the configuration

Newer posts
Older posts