3

I want to save log entries to my MySQL database from Zend Framework 2. I am using Zend\Log\Logger with a Zend\Log\Writer\Db writer. By supplying the writer with an array, one can choose which columns to save what data to (e.g. timestamp into a "log_date" column) and which data to save. Here is what I am doing:

$logger = new Zend\Log\Logger();

$mapping = array(
    'timestamp' => 'timestamp_column',
    'priority'  => 'priority_column',
    'message'   => 'message_column',
    'extra' => 'extra_column'
);

$logger->addWriter(new Zend\Log\Writer\Db($dbAdapter, 'table_name', $mapping));
$logger->err('some message', array('some extra information'));

The problem I am facing is that the array of column names and their values contain an incorrect column name for the "extra" column. Based on the array above, it should be inserting the value "some extra information" into the "extra_column" column. The problem is that the Zend\Log\Writer\Db class is using the letter "e" as the name of the extra column. This comes from the first letter of "extra_column" in my array above. For some reason, it is taking the first letter of "extra_column" and using it as the column name instead of the entire value.

I took a look at the source code. The mapEventIntoColumn method is being used to get the column names and values as an array. I copied in the relevant part of the method below.

// Example:
// $event = array('extra' => array(0 => 'some extra information'));
// $columnMap = array('extra' => 'extra_column');
// Return: array('e' => 'some extra information')
// Expected (without looking at the code below): array('extra_column' => 'some extra information')
protected function mapEventIntoColumn(array $event, array $columnMap = null) {
    $data = array();
    foreach ($event as $name => $value) {
        if (is_array($value)) {
            foreach ($value as $key => $subvalue) {
                if (isset($columnMap[$name][$key])) {
                    $data[$columnMap[$name][$key]] = $subvalue;
                }
            }
        }
    }
    return $data;
}

The $event parameter is an array containing the same keys as my $mapping array in my first code snippet and the values for the log message. The $columnMap parameter is the $mapping array from my first code snippet (array values are column names).

What actually seems to happen is that because I am passing in extra information as an array (this is required), the inner foreach loop is executed. Here, $key is 0 (the index) so it is actually doing like this: $columnMap['extra'][0]. This gives the letter "e" (the first letter in "extra_column"), which is used as the column name, where it should be the entire column name instead.

I tried to supply my own key in the extra array when calling the log method, but the same happens. The official documentation shows no examples of usage of the extra parameter. I want to insert information that can help me debug errors into my table, so I would like to use it.

Is this a bug or am I missing something? It seems really strange to me! I hope I explained it well enough - it is quite tricky!

2
  • 4
    It seems to me that it requires you to specify extra information as a name value map, e.g. ['somethingElseIWantToKnow' => 'Suns shining']. Thus, you'd have to set your mapping to ['timestamp' => ..., 'extra' => ['somethingElseIWantToKnow' => 'whats_the_weather']]. However, not having used the DB writer yet, I can only guess by looking at the sources. Commented Jan 24, 2013 at 8:32
  • @DanielM Thank you! That turned out to be the problem. I should have figured it out, but it helped to get another pair of eyes on it. :-) If you copy your comment into an answer, I will accept it. Thanks again. Commented Jan 24, 2013 at 14:03

1 Answer 1

2

Since Daniel M has not yet posted his comment as an answer, I will refer you to his comment which solved the problem.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.