Text

More Coding!

Wanting to give back to the open source community, I like releasing my work as open source software just in case someone else can use it too. A few months ago I released a few libraries (which I call “components”) and have been tinkering with them since then. After a bit of time, I felt like it was time to work on stabilizing them and having a 1.0 tag. I did another pass through all of the libraries and re-organized everything.

The re-organization resembles how the Symfony components are made available on GitHub. This should make it easy to add to your own projects, especially when using Packagist. The only exception is that the unit tests for each library are stored in one repository. The libraries are tied to the unit tests as submodules.

I just need to finalize the Log component I wrote, update both Event and Exception which rely on it, and I can finally release a beta version of everything. I will give it a couple months of releasing more betas and release candidates before settling on what would be a 1.0 release. I would very much appreciate input so that I can improve on them for your own use. The best way of doing this is to open issues in the respective repository.

The CODEAlchemy components:

Tags: projects
Text

PHP Logging, Exception Handling, and Event Management

Last year I wanted to use the newly released Symfony framework to create my own web applications. As I perused through its source code and documentation, I noticed that there were a lot of concepts that I could learn and use in my own software. I decided to scrap all of my existing work and start clean using my new found knowledge. The result of that work are a few libraries I have developed, and some more I will be releasing later.

All of the libraries I have released are unit tested and have both usage and API documentation available as part of their repositories. I would be more than grateful for bug reports and suggestions for improvement.

Log

The Log library, also named as the “CODEAlchemy Log component”, is a customizable log management library. I drew a whole lot of inspiration from Monolog, the logging library used by Symfony, and took it a little further.

The library is divided into four small parts:

  • Entry
  • Processor
  • Store
  • Manager

Note that I will describe the default functionality the logging library will provide. You are not limited to these defaults! You can use the bundled interfaces to create your own classes to expand on what the library can already do.

Entry

Log entries are instances of an EntryInterface class. Instances of this class not only contain the actual log message, but a whole lot of other potentially useful information. Some of which include: severity, origin of the message (file path, line number, class name, method), as well as the date and time of when it was created. Instances of EntryInterface classes also support additional custom attributes in case even more information needs to be added (see Processor below).

Processor

Log entry processors are instances of an ProcessorInterface class. These classes make use of a log entry’s ability to accept additional information through attributes. The included processors allow you to add information such as current memory usage, current peak memory usage, and web information such as request URI, request method, and the client’s IP address.

Store

Log entry stores are instances of an StoreInterface class. These classes are responsible for actually writing the log entry somewhere. The included store classes allow you to use any output stream, as well as a file.

Manager

Log entry managers are instances of an ManagerInterface class. Managers bring everything together so that you do not have to manually call all processor and stores on every log entry you wish to use. You simply add the processors and stores you want to use, and you just add log entries to the manager. The manager will take care of running the log entry through all of the registered processors, and then finally writing the log entry to all of the registered stores.

Exception

The Exception library, also named as the “CODEAlchemy Exception component”, is a customizable exception handling library. I created this library because I noticed a consistent pattern in the way I used errors and exceptions, and did not want to re-invent the wheel for each new web application I wrote.

The library is divided into three small parts:

  • Renderer
  • Log
  • Handler

Renderer

Exception renderers are instances of an RendererInterface class. Renderers do as their name implies: render exceptions. The included rendering classes allow you to choose between rendering for CLIs or in HTML.

Log

Exception logs are instances of an LogInterface class. Logs also do as their name implies: logging exceptions. The included log classes allow you to either log the exceptions using error_log() or the Log library I described earlier.

Handler

The exception handler is the class that brings it all together and actually receives the exceptions from PHP. You may only use one renderer and one log with the handler. Only one renderer may be used because it just does not make sense to use more than one. Only one log is used for keeping this simpler in the handler, but the log class itself may write to more than one log (see the Log library above).

The handler also provides a method to convert errors into exceptions. This makes for more stricter error reporting and will also provide error messages the same benefits that exceptions receive when this library is used. It’s not required that you use this method, but if you are serious about writing good code, it is a very useful thing to have.

The handler also takes care of not sacrificing stability over the features the library provides. If an exception is thrown by either the log or renderer, it attempts to recover and fall back to more reliable means of error logging and rendering. However, because errors cannot be caught, I suggest that you convert errors into exceptions so that those can be recovered from as well.

Event

The Event library, also named as the “CODEAlchemy Event component”, is my implementation of the observer pattern. The added twist is that the library supports logging and the sharing of relevant data.

The library is divided into three parts:

  • Subject
  • Observer
  • Dispatcher

Subject

Event subjects are instances of an SubjectInterface class. The subjects manage observers and notifies them when an update is available. The subject also doubles as a contain for shared data. The data can be accessed by using the subject instance as an array. A log may also be attached in order to log when an update is started, which observers are called and in what order, as well as the update process’s status.

Observer

Event observers are instances of an ObserverInterface class. The observers are on the receiving end of an update. They also receive the instance of the subject so that shared data can be retrieved and/or manipulated. An observer is where you would do all the work you planned on doing for a specific event.

Dispatcher

Event dispatchers are instances of an DispatcherInterface class. Dispatchers manage a collection of subjects and will event trigger the update process for the specified subjects. A log can also be attached in order to log when subjects are attached, detached, and updated.

Tags: projects
Text

CODEAlchemy Log Library

In my quest to find a modern, object oriented, PHP logging library, I found precious few. Because of the respect I have for Symfony and Sensio Labs, I decided to take a look at the Monolog library that was bundled with it. I must give props to Jordi, I can see why it was decided to be include it with Symfony.

However, I did not like the design of the library. This is a matter of personal preference. I did not like that it defined its own severity codes, while PHP offers its own standard set of error constants. I also did not like the use of processors and formatters.

Since this is just a difference of opinion on how logging should be handled, I decided to write my own library instead of bugging Jordi with sweeping changes.

My Log library is the result of that effort. It’s

  • simple to use
  • fully unit tested with 100% code coverage
  • PSR-0 compliant
  • offers decent examples on usage
  • released under the BSD license

I even took inspiration from Monolog. The Queue class is similar to Monolog’s FingersCrossedHandler. It holds onto all of the log entries until a certain kind of entry is added. Once that special entry is added, all of the queued up entries are dumped to the log along with the special entry.

You can find examples on using the library, including the Queue class, in the repository.

Tags: projects