Creating a custom XML logger for SugarCRM 7

I recently ran across a question on StackOverflow in which the original poster asked about creating a custom XML logger for SugarCRM. He was wondering where to put his custom class and some of the particulars surrounding this so I thought I’d pitch in and help out.

I created my own custom XML logger class – SugarXMLLogger – and saved it at custom/include/SugarLogger/SugarXMLLogger.php. I then applied it to the Ping API for testing both as a replacement for fatal level logging and as a replacement for the default logger. Since the functionality of the logger is intended to be simple, I didn’t feel the need to extend SugarLogger. However, I did feel it at least appropriate to implement LoggerTemplate so that the integrity of the logger among the stack of loggers was kept in tact. If you want the fullness of SugarLogger in your custom loggers then you should extend SugarLogger. However, for a simple XML logger that wasn’t absolutely necessary.

As far as the log is concerned, I kept all the same information as is normally in sugarcrm.log with the only change being how it is stored. Since XML is structured it made sense to structure the logged information accordingly. So, without further ado, here is the code for the SugarXMLLogger…

The SugarXMLLogger Class

<?php
/** 
 * Save to custom/include/SugarLogger/SugarXMLLogger.php
 * 
 * Usage: 
 * To make one particular log level write to the XML log do this:
 * ```php
 * <?php
 * LoggerManager::setLogger('fatal', 'SugarXMLLogger');
 * $GLOBALS['log']->fatal('Testing out the XML logger');
 * ```
 * 
 * To make all levels log to the XML log, do this
 * ```php
 * <?php
 * LoggerManager::setLogger('default', 'SugarXMLLogger');
 * $GLOBALS['log']->warn('Testing out the XML logger');
 * ```
 */
 
/**
 * Get the interface that this logger should implement
 */
require_once 'include/SugarLogger/LoggerTemplate.php';
 
/**
 * SugarXMLLogger - A very simple logger that will save log entries into an XML
 * log file
 */
class SugarXMLLogger implements LoggerTemplate
{
    /**
     * The name of the log file
     * 
     * @var string
     */
    protected $logfile = 'sugarcrm.log.xml';
 
    /**
     * The format for the timestamp entry of the log
     * 
     * @var string
     */
    protected $dateFormat = '%c';
 
    /**
     * The current SimpleXMLElement logger resource
     * 
     * @var SimpleXMLElement
     */
    protected $currentData;
 
    /**
     * Logs an entry to the XML log
     * 
     * @param string $level The log level being logged
     * @param array $message The message to log
     * @return boolean True if the log was saved
     */
    public function log($level, $message)
    {
        // Get the current log XML
        $this->setCurrentLog();
 
        // Append to it
        $this->appendToLog($level, $message);
 
        // Save it
        return $this->saveLog();
    }
 
    /**
     * Saves the log file
     * 
     * @return boolean True if the save was successful
     */
    protected function saveLog()
    {
        $write = $this->currentData->asXML();
        return sugar_file_put_contents_atomic($this->logfile, $write);
    }
 
    /**
     * Sets the SimpleXMLElement log object
     * 
     * If there is an existing log, it will consume it. Otherwise it will create
     * a SimpleXMLElement object from a default construct.
     */
    protected function setCurrentLog()
    {
        if (file_exists($this->logfile)) {
            $this->currentData = simplexml_load_file($this->logfile);
        } else {
            sugar_touch($this->logfile);
            $this->currentData = simplexml_load_string("<?xml version='1.0' standalone='yes'?><entries></entries>");
        }
    }
 
    /**
     * Adds an entry of level $level to the log, with message $message
     * 
     * @param string $level The log level being logged
     * @param array $message The message to log
     */
    protected function appendToLog($level, $message)
    {
        // Set some basics needed for every entry, starting with the current
        // user id
        $userID = $this->getUserID();
 
        // Get the process id
        $pid = getmypid();
 
        // Get the message to log
        $message = $this->getMessage($message);
 
        // Set the timestamp
        $timestamp = strftime($this->dateFormat);
 
        // Add it to the data now
        $newEntry = $this->currentData->addChild('entry');
        $newEntry->addChild('timestamp', $timestamp);
        $newEntry->addChild('pid', $pid);
        $newEntry->addChild('userid', $userID);
        $newEntry->addChild('level', $level);
        $newEntry->addChild('message', $message);
    }
 
    /**
     * Gets the user id for the current user, or '-none-' if the current user ID
     * is not attainable
     * 
     * @return string The ID of the current user
     */
    protected function getUserID()
    {
        if (!empty($GLOBALS['current_user']->id)) {
            return $GLOBALS['current_user']->id;
        } 
 
        return '-none-';
    }
 
    /**
     * Gets the message in a loggable format
     * 
     * @param mixed $message The message to log, as a string or an array
     * @return string The message to log, as a string
     */
    protected function getMessage($message)
    {
        if (is_array($message) && count($message) == 1) {
            $message = array_shift($message);
        }
 
        // change to a human-readable array output if it's any other array
        if (is_array($message)) {
            $message = print_r($message,true);
        }
 
        return $message;
    }
}

The structure of the log

<?xml version="1.0" standalone="yes"?>
<entries>
    <entry>
        <timestamp>Wed Oct  8 11:56:04 2014</timestamp>
        <pid>89160</pid>
        <userid>1</userid>
        <level>fatal</level>
        <message>Testing out the XML logger</message>
    </entry>
</entries>

How to log only fatal logs to the XML log

<?php
LoggerManager::setLogger('fatal', 'SugarXMLLogger');
$GLOBALS['log']->fatal('Testing out the XML logger');
?>

How to log all logs to the XML log

<?php
LoggerManager::setLogger('default', 'SugarXMLLogger');
$GLOBALS['log']->warn('Testing out the XML logger');

Why I love working for SugarCRM

SugarCRM Chrome Bottle Opener It’s not everyday that a man finds work that he loves. Hell, in today’s economy, a lot of men can’t find work at all, let alone rewarding work that he enjoys. I’m one of the fortunate few who has been very blessed in my career path as it relates to doing work that I enjoy doing, being good at what I do and being able to provide for my family. But I have to say that I have never been quite as happy with my job as I have been since January of this year.

Backstory
In mid-December 2011 I was approached by a recruiter through email. Why I remember this is pretty simple: he didn’t sugar coat his email with a bunch of recruiter mumbo jumbo and buzzwords, nor did he include a job description or any of that. He straight up said he was a headhunter and was looking for a Senior Software Engineer for a well funded, private company in the bay area. After a couple of emails, we setup a time to talk on the phone. That in and of itself is a rare occurrence because I don’t talk to too many recruiters since most bomb out during the email phase. But what made this an especially odd thing was that as we talked, he engaged me very quickly about what I like to do, what I am good at and what I wanted to do with my career. We talked for about a half hour and he asked me if I’d be open to interviewing with his client if he could get me in for an interview. I told him I would be for a couple of reasons, the most prominent being that A) I was looking for work as I wrapped up a short term contract project, and B) the company he was talking about – SugarCRM – was a company I had known about and was interested in for quite some time. This call took place on a Friday. On Saturday he called me to tell me that he had scheduled an interview for me on Monday, December 19 at 2:00 in Cupertino. And from here on begins the real story of why I love working for SugarCRM.

In the beginning
The Monday that I was supposed to interview came around and I hadn’t heard from the recruiter. I thought it was kinda odd but figured that maybe something needed to be hashed out on his end so I went about my business that day. Then, at about 12:30, I got an email from him with the address for SugarCRM and a message saying they were expecting me at 2:00 pm. Since I was still out with the kids I had to hustle home and get myself somewhat presentable for an interview at 2:00 in Cupertino. I did my best, and managed to get some jeans and a golf shirt on before heading out the door. I got to Sugar just before 2:00.

I was given some papers to fill out while I waited for the person that was going to interview me to come get me. Turned out, there were several people that were going to interview me and the first fellow came out pretty quick. As we walked through the halls toward the interview room I began to get a little nervous. But once we sat down and started talking, I had the pleasure of experiencing the funnest interview I had ever been on. I actually interviewed with three different Engineers, all of whom asked me questions that were both challenging but practical. And all of them had a coding exercise that we worked on together to solve. I got a really good vibe from the first three guys but when the fourth person walked in, things changed a little bit. You see, the fourth person was a VP and there really weren’t any technical questions at that point. From there it became more a matter of when I could start and some of the other logistical questions that you might find in the late stages of an interview. And when I left there, just before 5:00, I had an odd sense that it might have gone pretty well. I didn’t know how well until, about 20 minutes later, I got a call from my recruiter telling me they had drafted an offer letter for me.

I started working for SugarCRM on January 9, 2012. My first day at the office was the first day of the 2012 Sales Kickoff week. It was also the first day of an Engineering Sprint featuring a good number of engineers, including all HQ engineers and remote engineers from just about everywhere. It was chaotic to say the least, and the pace in the office that day was absolutely frenetic. In all honesty, I was a little taken aback by it all because I had never been involved in such a large scale engineering effort nor had I ever been part of a large engineering team before. But after spending my first day getting my development environment set up, I was off and running with my first assigned tasks. Looking back on those first few days at work now feels like a big blur because of how fast things went, how much I learned and how many people I met. It was a crazy, fast, amazing week and without a doubt, it was the best first week I’ve ever had at a new gig ever.

Can it really be this good?
Fast forward to today. I’ve been with Sugar for six months now. I’ve learned a lot about our product, our codebase, our engineers, our company and our future plans. I’ve survived the on-boarding process, made it through a couple of team transitions and have made some pretty decent contributions to the application. I’ve made some friends, helped some folks and have essentially become part of the team. But of all the things that the last six months have brought to my life, what stands out to me the most is how much I enjoy going to work everyday.

It might sound strange to hear someone talk about how much they love their job. I know there are a lot of people that are either out of work right now or are working at a job that is killing them slowly. I’m not trying to make anyone jealous, but I am happier in my work now than I have ever been before. And anyone that knows me knows that this is not only a truth but one that I’ve not been able to say for a long, long time.

So what is it about my job that makes it this good? Well, I’ve been thinking about that as I drive to and from work from time to time (one of the many things I love about my job is the ability to work remotely). So I decided that I’d share the love a little bit. I mean, you never know, you might just be an engineer looking for a new place to call home, right? 🙂 So here are just some of the reasons why I absolutely love working for SugarCRM, in no particular order and not necessarily inclusive of all of the reasons I love this place.

  1. What we’re working on
    I’m not sure if everyone knows yet just what CRM is. I know I didn’t until my last job, and even then, it wasn’t nearly as clear to me as it is now. Customer Relationship Management… it sounds like an industry buzzword used by someone trying to sell you something when you read it like that. But when you listen to our founder – Clint Oram – describe his vision of CRM, and what gave him the idea to develop a CRM application to begin with, you’ll see that what we are working on at Sugar is so much more than an application or a buzzword. We are working toward the success of every organization that chooses our software and services. We are working on the notion that if we can help others become successful we in turn can become successful. And the vision that our company has to ensure the continued success of our users floods our entire engineering organization. There’s just something exciting about working toward a goal that is bigger than you.

  2. How we’re working
    If, as an engineer, you’ve never been involved in agile development you are missing out. I had never been involved in true agile development, although I had employed some of the methodologies in previous jobs, so that was a bit of a shock to my system at first. But it happened that I learned to love it pretty early on and have been able to embrace the speed and iterative nature of it. There is also something to be said about accountability, which agile also necessarily involves, and the freedom to engineer in the way that works best for you while taking full credit for your successes and standing behind your mistakes. Yes, I said mistakes. They happen, even (if not especially) in agile environments. And the best part about that is, when things break, no one flies off the handle or starts panicing. You simply engineer your way through it and let your brilliance flow.

  3. Who’s doing the work
    There’s something to be said for working with absolutely brilliant people, especially when those people are really cool and really friendly while being brilliant. I have the pleasure of going to work everyday with some of the smartest, most intelligent, sharpest minds that a company could put together. These folks are from all over the world as well as right here in the United States (some are even in Cupertino 😉 ). The engineers that I get to work with are never short of ideas, never slow to offer help, are always thinking of new and challenging ideas, and simply do not even consider that something can’t be done. And it seems that there isn’t a single person in Engineering and Development that doesn’t always have some sort of idea, some knowledge that you never even knew existed or some way of doing something that is totally fresh and new.

    Something else that totally amazes me everyday are some of the names within the PHP community that I get to work with. I know that distilling things down to PHP seems a little concrete in nature, but anyone that knows me knows that I am a PHP fanboi to the core. It’s the language I learned on and the language that has led to the career that I enjoy. So for me, getting to mix it up with some of the more well known names in the PHP world on a daily basis is kind of amazing. I won’t spill the beans on these people are out of respect for their privacy, but if you are as in love with the PHP language as I am, then you’d love working here.

  4. What we’re working with
    As much a fanboi as I am of PHP, I am more a fan of doing things the right way and the best way possible. To that end, PHP is NOT the end all, be all of technologies even if it is the core technology of the product we ship. And that right there is another thing I love about Sugar. We use tools from a mixed bag of technologies. We use Ruby applications, Python applications, Java applications… we use different databases, different environments and different platforms. There isn’t anything that is really off limits when it comes to making our jobs more efficient and more effective. And this appeals to me greatly because that means that whatever is the best tool for the job, that’s the tool we get to use, even if we don’t know it that well or it isn’t the same platform as our product is.

  5. Freedom to be creative
    I’m pretty sure that of all the cool qualities of working at Sugar this one right here is the one that speaks the loudest to me. Never before have I been a part of an organization that literally puts you in the driver’s seat. When you’re given a task, you own it. What you build, you stand behind. It’s yours. And whatever it takes to allow you to be able to produce something worthy of putting your name on it, you’re allowed. Need snacks, coffee, red bull or chips? Done. Need beer? Done. Need leather couches to kick back on while you code? Done. Need to take a break and school an intern on what ping pong is really about? Done. Or perhaps you’re feeling like working in the office isn’t the best way to get things done for the day. Perhaps you want to work at a local coffee shop or even work at home. Well, guess what? You can do that to. You are literally put in command of your own destiny and given whatever tools you need to be a successful engineer.

    I don’t think I’ve ever been as productive in my work, and in as enjoyable a fashion, as I have been while at Sugar. For me, there hasn’t really been a way to not be productive because whatever makes me the best programmer I can be for that day is offered to me.

  6. The learning never ends
    Not a week goes by that I don’t learn something new from someone. The experience that our engineers have, the curiosity that we all have, the development we are all doing leads us down a path of continued learning that can only make us better as we progress toward our goals. I mean, just in the last four weeks alone, I’ve learned more about Javascript than I think I had ever known before, I’ve learned about PHPUnit data providers place in the call stack and I’ve learned about Git submodules. In the weeks and months prior I’ve learned about some oddities in the way that Google manipulates email headers when being sent through their SMTP gateway when using credentials that don’t match the sender information, I’ve learned about licensing variations and I’ve learned how to automate some common development tasks by creating macros in my IDE. I am always learning, and at the same time, I am teaching. Which allows our entire team of engineers to continue to sharpen our skills while helping other engineers sharpen theirs.

Wrapping it up
I know it sounds a lot like I’m doting on my company. The truth is, I am. I am quite literally happier in my work now than I have ever been before. I feel a sense of purpose, a sense of determination and a sense of pride in doing what I do. I feel like there is a much bigger effort at play and that, while my contribution to that effort might be small, it is still significant. And even though I’ve laid down probably 2,500 words to describe why I feel this way, those words still fail to capture the essence of why every software engineer should have the experience of working at SugarCRM.

To that end, let me say that I am so not ashamed to plug the employment opportunities at Sugar right now. We are growing so fast right now that, even though we are bringing new engineers in regularly, we are still looking for top level talent. So if you’re looking for a change in your career, and you are stellar software engineer, you really should give us a look. Making that choice has been one of the best things I’ve ever done in my life.

FULL DISCLOSURE NOTICE: The links to the open positions at SugarCRM that I’ve added to this post contains information that will associate your click through and subsequent interest in SugarCRM jobs to me. It is yet another perk of the job, getting bonuses for bringing new talent on board. If this troubles you feel free to hit the SugarCRM careers page directly. Just know that if you do that, Cthulhu will invade your sleep and eat all the kittens that you dream about nightly. Ok, that probably won’t happen, but if it does, you can’t say I didn’t warn you.