Symfony: Log outgoing responses with kernel events

One of the nicest features of Symfony2 is the Request/Response paradigm for processing a HTTP request and then sending a response back to a client. At a high level, Symfony’s HttpFoundation component provides an object oriented abstraction to easily deal with HTTP requests and generate responses to send back to a client. Assuming application code correctly uses HttpFoundation, it will only interact with request variables through the Request class, as opposed to $_REQUEST, and only send output using the Response class, as opposed to an “echo”. Because of this contract, the framework as a whole makes it easy to manipulate responses before they’re sent back to a client.

A typical use case that leverages this would be logging API responses before they’re sent back to a client. As much as an API might be RESTful, at some point it’s easier to debug things when you can see the responses that clients have been receiving. OK great so how do you do it? It’s actually pretty straightforward, just create a class to receive the “kernel.terminate” event and register it as a service with the appropriate tags:

And then create the class where you want to manipulate or log the requests:

And that’s about it!

Note: Per Andras’ comment below the event has been switched to “kernel.terminate”.

Phonegap: Fixing black bars on iOS7/iPhone5

Last week, we were using Phonegap Build to build an iOS IPA for a project an ran into an odd issue. When we launched the app on an iPhone 5 running iOS7 black bars appeared at the top and bottom of the screen. On top of that, when launching the app we were observing the same issue with the splash screen.

In typical Phonegap fashion, Googling for people suffering from similar issues brought back dozens of results across several versions each with a different root cause and solution. One of the first promising leads we noticed was this comment in the top of the default Phonegap template:

Unfortunately, that comment seems either be invalid or the issue has since been resolved since removing those meta attributes had no effect.

As it turns out, the issue is that the “config.xml” file created by the default Phonegap “Hello world” project is missing an entry for the iPhone5’s screen size. Oddly enough, there’s actually a splash screen image of the correct height in the demo project but its not referenced in the config file. To resolve this issue, you just need to add this line to your config.xml:

Just make sure that you have a file named “res/screen/ios/screen-iphone-portrait-568h-2x.png” where the rest of your splash screens are and you should be good to go.

How will HHVM influence PHP?

Over the last few weeks, there’s been a slew of HHVM related news from the “We are the 98.5%” post from the HHVM team to the Our HHVM Roadmap from the Doctrine team. With the increasing excitement around HHVM, it’s becoming clear that the project is going to play an important role in the evolution of the PHP ecosystem. Even though it’s in it’s early stages, what influences will the HHVM project have on the PHP ecosystem as a whole?

Force the creation of a language spec

In contrast with other languages like Python or JavaScript, PHP has no formal language specification. There’s some extended discussion on this StackOverflow thread with links to PHP internals posts but the final consensus is that there isn’t a defined EBNF grammar for PHP or a “specification” for how things should work. Instead of a spec, the behavior of PHP has become defined by how the Zend interpreter works since it’s been the only viable implementation of the language to date. HHVM changes this situation by introducing another run time for the language, a developer won’t necessarily know if their code will be deployed on Zend or HHVM. Because of this, the community will have to develop a language specification to ensure that any language changes are implemented identically in both run times.

Willingness to introduce BC breakage

One of the hallmarks of PHP has been its strong adherence to backwards compatibility, five year old code written to target PHP4 will generally run today on PHP5+ without any modifications. This has generally been possible because changes to PHP the language didn’t change behavior which would of broken previously working code. Because of this, many of PHP’s long standing syntax issues haven’t been fixed and changes to the standard library have been largely avoided. If HHVM emerges as an alternative runtime, some of this hesitation should be removed since if only “newer” code will run on HHVM it would be conceivable to introduce a “HHVM compat” mode into the Zend implementation which could include BC breaking syntax changes.

JIT into Zend

Just in-time compilation has been shown to dramatically increase the execution speed of interpretted programming languages and it’s one of the key benefits of the HHVM interpretter. HHVM identities “hot code” which is repeatedly executed and then compiles those blocks to native code. The result of this is that those “hot code” sections execute faster since they’re running native code instead of the interpreted op codes. As HHVM becomes more popular, I think we’ll see cross pollination of JIT into Zend similar to how Firefox adopted JIT after Google released Chrome.

Anyway, it’s still early but the emergence of HHVM as an alternative PHP runtime will definitely have a positive influence on the PHP ecosystem. From technology sharing to increased competition, the future is bright and I’m excited to see how PHP evolves in the next few years.

Hive: How to write a custom SerDe class

We’ve been using Hive a bit lately to help clients tackle some of their data needs and without a doubt one of the most powerful features is Hive’s SerDe functionality. Taking a step back, Hive is an open source Apache project that lets you run “SQL Like” queries using Hadoop on data that you have in HDFS. It’s a lot of moving pieces but what it fundamentally comes down to is that Hive will let you run what look like SQL queries across the text files that you have in HDFS. A typical use case would be using Hive to run ad-hoc queries across web server (like nginx) logs. Want to a breakdown of response times by frontend web server? Hive would let you do that.

SerDe?

SerDe is actually short for Serialize/Deserialize and its the mechanism that Hive uses to make sense of your text files in HDFS. Lets take a typical nginx log line:

Now the magic comes in how Hive uses a SerDe to translate a line like that into something that’s queryable. This is contrived but lets assume that for some reason we’re interested in querying on the client IP address and the request size of each log line. So we’d be interested in creating a table that looks like:

Turns out, Hive makes this particularly easy. You’d end up using the RegexSerDe to match a regular expression and then extract the two fields you’re interested in.

A custom one

The next step after extraction is to do some transformation during the extraction stage and this is where the custom SerDe comes in. For example, lets say that you wanted to geocode the client’s IP address and also convert your dates into Unix timestamps. So your table would be something like:

Your custom SerDe would let you do exactly this. You’d be able to use something like the MaxMind database to geocode your IP addresses and then use some extra Java to convert your timestamps.

Unfortunately, there doesn’t seem to be too much documentation on how to actually write a custom class so here’s a couple of tidbits I’ve picked up:

  • It looks like at some point the SerDe class was refactored so depending on what Hive version you’re using you’ll need to extend a different class. On Hive 0.11 the class you’ll want to extend is “org.apache.hadoop.hive.serde2.SerDe”
  • You’ll need to include a couple of JARs in order to get the class to build. I had to include commons-logging-1.0.4.jar, hadoop-0.20.1-core.jar, hive-contrib-0.10.0-cdh4.4.0.jar, hive-exec-0.10.0-cdh4.4.0.jar, junit-4.5.jar
  • As noted above, you need to pull the specific versions of the JARs that you’re going to end up running this SerDe against
  • Make sure you target the right Java JRE version. If your servers are running Java 1.6 and you target 1.7 you end up getting really cryptic error messages.
  • If you create a table using your SerDe, you’ll need to have that JAR available to drop that table

The best way I’ve found to bootstrap this is to create an Eclipse project, include the necessary JARs, and then get the RegExSerDe to build inside the project. Once that works, test the JAR by creating a table using it and then you’ll be able to modify the class from there.

Even with my awful Java, the RegexSerDe class was easy enough to grok and then modify as needed.

Stuck? Need Help?

Drop me a comment or shoot me an email and I’ll do my best to help you out.

Symfony2: Using FOSUserBundle with multiple EntityManagers

Last week, we were looking to setup one of our Symfony2 projects to use a master/slave MySQL configuration. We’d looked into using the MasterSlaveConnection Doctrine2 connection class, but unfortunately it doesn’t really work the way you’d expect. Anyway, the “next best” way to set up master/slave connections seemed to be creating two separate EntityManagers, one pointing at the master and one at the slave. Setting up the Doctrine configurations for this is pretty straightforward, you’ll end up with YAML that looks like:

At face value, it looked like everything was working fine but it turns out they weren’t – the FOSUserBundle entities weren’t getting properly setup on the slave connection. Turns out, because FOSUserBundle uses Doctrine2 superclasses to setup it’s fields there’s no way to natively use FOSUserBundle with multiple entity managers. The key issue is that since the UserProvider checks the class of a user being refreshed, you can’t just copy the FOSUserBundle fields directly into your entity:

So how do you get around this? Turns out, you need to add a custom UserProvider to bypass the instance class check. My UserProvider ended up looking like:

And then the additional YAML configurations you need are:

The last step is copying all the FOSUserBundle fields directly into your User entity and update it to not extend the FOSUserBundle base class. Anyway, that’s it – two EntityManagers and one FOSUserBundle.