Developing a Zabbix ExtJS frontend: Part One

Richlv asked me to give feedback about my experiences on the Zabbix PHP code, and this is the first blog post in that series. This posting is not intented as a “rant” at all, but as feedback and discussion for the development of Zabbix.

Why another frontend isn’t needed, but most probably wanted

There is always a controversy if somebody comes up with a new idea. People argue that there’s no need for something new, but obviously they miss one point: The person who says: “I want something new” really wants something new.

The current frontend has some drawbacks. However, the main drawback is the navigation:

The workflow is sometimes very unhandy. You have to switch back and forth between menu items, and end up with many open tabs or windows to achieve a single task.

An example of this is when you create a new host and notice that you’d better put some items into a template. You would need to save the host and navigate to the templates, create a template, navigate to the items, create the items, the triggers and then get back to the host to apply the template.

The exact same issue occurs when you have an alert; you don’t have the item’s history graph at your fingertips (=one click and you see the related charts).

In theory, much usability could be added in the existing frontend, but this would need a huge effort, due to the old-style implementation of the frontend.

How can ExtJS help here?

ExtJS is a JavaScript frontend library which is implemented in an object-oriented way. This helps with code deduplication and enables developers to implement reusable components. I’ve had very good experiences while working on the PartKeepr project.

In fact, while working on PartKeepr, I enjoyed the complete separation of business logic (which goes onto the PHP side) and frontend (ExtJS side).

Now where are the problems?

There are quite a few. First of all, ExtJS doesn’t support JSON-RPC, while JSON-RPC is the only API Zabbix currently supports. I can’t really judge if JSON-RPC is common or not, but I do feel that a RESTful API is more common. I solved that by implementing a wrapper which takes RESTful requests on the one side and converts them into JSON-RPC and calls the Zabbix API from there.

Another issue is that Zabbix doesn’t really use normalized entities. There are many tables, which are re-used for different things (example: Hosts and Templates share the same table). Some fields are probably used for hosts and not for templates, and vice versa (I’m really not sure about this, I haven’t created an in-depth analysis so far). If normalized entities would exist, one could write entity classes based on that, which in turn could implement the serialize/deserialize methods. That would give the following benefits:

  • Implementing additional Web APIs is very easy, because the entities themselves handle their serializing/deserializing.
  • You could minimize the Web API call implementations to a minimum when using an ORM. Right now, each API call has 1000-2000 SLOCs and if there’s something which needs to be added, like pagination, you would need to touch every Web API call. In turn, when using an ORM and an OO model, you would only have to change a single base class to make that happen.
  • Duplicate business logic could be unified, where it doesn’t matter if the Web API or the native PHP frontend uses the entity API; the business logic would stay exactly the same.

There are probably more benefits, such as reduced code error rate and better unit testing.

Another issue is the database model: It is purely created by a set of different SQL scripts for each database type. Migrations from one version to another is achieved by running an update SQL script. There’s no real code which could aid with type migrations in order to create a normalized database model. Also, it seems that Zabbix is using inappropriate data types (e.g. using int(11) on MySQL for boolean instead of boolean and also int(11) for timestamps). Additionally, it is virtually impossible to know what each column in the database does.

Conclusion

Zabbix was first released in 2001. Since then, much has happened. However, the code could be improved in many many places; which is a virtually impossible task to achieve for a very specific version. As Zabbix is used by customers and Zabbix SIA creates revenue out of Zabbix, any code refactoring needs to be done very carefully.

As much as I’d love to create a fork and throw in modern technologies like Symfony2 and Doctrine2, this would not be practial. As the plans for Zabbix 2.0 are already settled and customers are still using PHP 5.2 due to RHEL5 and others; this is virtually a KO for Symfony2 and Doctrine2.

While implementing the ExtJS frontend, I try to give as much feedback and patches to the Zabbix Developers as I can. I am not sure if it is even possible what I have in my mind for an ExtJS frontend; however, I am sure that it can be done, even with many nasty workarounds.

  1. Oleksiy Zagorskyi

    s/renevue/revenue/

    Ragards,
    zalex

  2. Hi Oleksiy,
    I saw your post by chance, when looking for a way to bypass that terrible zabbix default frontend. At first, I studied how to adapt their code to my needs. Unfortunately, it was proven to be impossible or at least extremely hard.
    Now I’m working on reusing their json rpc API, like you did. In fact, my approach is based on Symfony 2 and Doctrine 2 :grin:. There is an issue that I haven’t faced yet, but this scenario can change very soon. How are you dealing with changes in their database model? My (future) problem comes from the fact that new requirements have been demanded to me and most of them needs extra fields to be put into the existing model.
    I hope to hear from you and maybe we can help each other :mrgreen:

Add Comment Register



Leave a Comment


NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">