Building Internal Tools

Andrew Jensen - PowerStandings

ISDC Developer Training:

Regular Training Meetings

  • Learn new skills
  • Collaborate with other teams
  • Make our lives better

Regular Training Meetings

  • Ask questions during the presentation
  • Think about how to help your team
  • Trade ideas with other teams

Building Internal Tools

Find the Pain,

Find the Solution

The Lean Startup:

Pains your team might feel

  • We do manual process X all the time
  • It's hard to onboard employees because of problem X
  • Our system is unstable due to thing X

Our Software Stack

Message Queue

(RabbitMQ)

Joule Processor

(Golang)

Socket Server

(Crossbar)

In-memory

Database

(Couchbase)

 

STA

(PHP, MySQL)

Our Pain:

  • We run a lot of services
  • Our services crash
  • We need to know why
  • We need to know before others

What pains do you and your team feel right now?

Question:

Our Solution

Our Pain:

Services are crashing and we don't know why

Our Solution:

Build a monitor dashboard for our team to use

Technical Requirements

  • Monitor all environments
  • Maintain open connection with socket server
  • Flexible, modular
  • Future: send alerts

Design Requirements

  • Easy for developers to run
  • Easy for everyone to access and understand

Is this a waste of time?

Not if the pain is

big enough.

(live demo)

The monitor's stack

Dashboard

(React)

Monitored Services

API Server

(Node)

Why Node?

  • Our team uses PHP and Javascript
  • PHP didn't meet technical requirements
  • Massive community support

Why React?

  • One-way data flow: good fit for our project
  • React projects are hard to start but easy to maintain

What about my team?

  • This dashboard is ready to fork and use
  • Use whatever is appropriate for your team

Now is a good time to learn Node and React.

QA → Dev?

PHP, C#, Java  Javascript?

meetup.com/ProvoJS

Aug 26, 7pm:

Perspectives on CSS

The Code

Create a Service to monitor

var ServiceInterface = {

    initialize: function(config) {
        // Should start monitoring the service,
        // opening persistent connections if necessary
    },

    update: function(callback) {
        // Should communicate with the service and update the state
    },

    get: function() {
        // Should return the current state of the service
    }

};

Services are registered and initialized

ServiceManager.registerServices([
    'couchbase',
    'mongo',
    'mysql',
    'psn',
    'rabbitmq',
    'crossbar'
]);

app.get('/status', function(request, response) {

    response.json(ServiceManager.getStatus());

});

Status is returned as JSON

{
    "crossbar": {
        "checked": true,
        "online": true,
        "connections": 9001,
        "process": { ... }
    },
    "rabbitmq": {
        "checked": true,
        "online": true,
        "queue": { ... }
    },
    "psn": {
        "checked": true,
        "online": true,
        "instances": [
            {
                "name": "JP-1",
                "healthMonitor": { ... }
            },
            { ... }
        ]
    }
}

React components visualize the status

var Home = React.createClass({
  // ...
  render: function() {
    return (
      <div className="dashboard">
        <div className="details">
          <PSNDetails status={this.state.services.psn} />
          <SocketServerDetails status={this.state.services.crossbar} />
          <RabbitMQDetails status={this.state.services.rabbitmq} />
        </div>
        <div className="services">
          <div className="panel">
            <h2>Services</h2>
            <ServiceWidget title="MySQL" service={this.state.services.mysql} />
            <ServiceWidget title="Mongo" service={this.state.services.mongo} />
            <ServiceWidget title="RabbitMQ" service={this.state.services.rabbitmq} />
            <ServiceWidget title="Couchbase" service={this.state.services.couchbase} />
            <ServiceWidget title="Crossbar" service={this.state.services.crossbar} />
            <ServiceWidget title="PSN" service={this.state.services.psn} />
          </div>
          <RefreshPanel clickHandler={this._triggerRefresh} />
        </div>
      </div>
    );
  }
});

Fork the code:

Power Standings /

ps-monitor

Conclusion

When should you build

an internal tool?

Question:

What tools have you built for your team?

Two Questions:

What tools does your team need right now?

What questions do you have for other teams?

Final Question:

Thanks

andrew.jensen@insidesales.com

ISDC - Building Internal Tools

By Andrew Jensen

ISDC - Building Internal Tools

  • 626