• Cory von Wallenstein 8:04 pm on June 14, 2011 Permalink | Reply
    Tags: allspaw, , etsy,   

    Takeaways from John Allspaw Talk at Velocity 2011 

    While the title of this talk by John Allspaw (@allspaw) was intriguing (Advanced Postmortem Fu and Human Error 101), it didn’t really do it justice.

    John’s talk broke through all of the BS of “which tools do what”, and got to the core of the challenge we all in the #DevOps community face: we’re all human, we’re going to make mistakes, and our success or failure will largely be governed by the strength of the culture we’ve assembled around ourselves.

    How popular are these get togethers? Standing room only at #velocityconf. So please excuse my “side angle” slide photos… it’s the only spot I managed to claim as my own!

    So, without further ado, my big takeaways from @allspaw’s talk.

    Crisis Patterns

    There is a flow of events that can be found when looking back at a problem. It looks something like this, all leading up to the final event: the post-mortem.

    The problem starts, and from there, the states that unfold are:

    1. Detection
    2. Evaluation
    3. Response
    4. Stable
    5. Confirmation
    6. All Clear, followed by a Post Mortem

    And on top of these states over time, you know where your stress levels fall:

    If you’re monitoring sucks, and for some period of time the problem goes undetected, your stress curve gets compressed quite a bit, but the flow of events is still the same.

    Where your systems, tools, teams, culture, and ultimately, your entire organization will get put to the test, will be when you’ve detected a problem, evaluated it, and are in the process of responding… and it takes a long time to fix the problem. These are the most stressful of all scenarios, and it’s a scenario we all strive to avoid.

    So, what can be done during Post Mortem to better prepare ourselves for the future?

    Post Mortem

    Folks have written at length on techniques of root cause analysis for identifying “what went wrong?”

    Five Why’s: For each answer to “Why?”, ask another “Why?”

    Swiss Cheese: What I can only describe as “Allspaw’s Swiss Cheese”, building a mental model around layers of protection against failure (the cheese) and the complex interactions that can lead to failure (the holes in the cheese).

    What, you don’t believe me?

    Many more efforts (both commercial and academic) have spent significant time looking into techniques and categorizations, but deliver limited real-world value. So, what is valuable?

    There Is No Root Cause

    What is valuable is stepping back and understanding that there is no single root cause!

    These are complex systems. They have many, many interacting components. Not the least of which are the human beings that have created and are responsible for these systems. The most challenging problems are almost always systemic in origin.

    It’s not just a “web server” that failed… it’s that a feature on the roadmap that was supposed to go out yesterday actually went out today (due to miscommunication from a poor dashboard design and the fact that the DBA’s car broke down yesterday so folks made a decision to delay) and news of the feature was picked up by TechCrunch sending HUGE amounts of traffic to the site and putting HUGE strain on the servers which were underprovisioned (running low on that last round of funding…) and no one was watching for this because… my favorite part… the entire ops team was at Velocity.

    The problems of systemic origin do not benefit from a traditional root cause analysis. Even when applied, most folks conclude the problem was “Human Error”, but what value is that conclusion? It’s not like people come into work today planning on taking down the web site! Nobody comes into work with the intention of doing a bad job. The only real solution to these systemic problems is as complex as the cause: it comes down to the people, and the culture those people have built. So, if you end your root cause analysis with “human error”, you have to dig further. You have to look at your culture that led to that failure.

    What Can We Do To Improve Our Culture?

    A lot. A couple of ideas from John:

    • A Failure Gone Wrong is a Success: Rather than evaluating your failures and trying to figure out what went wrong, evaluated your successes and evaluate what went right. Maybe you did 100 code pushes, and 6 caused problems. If you only focus on the failures, you have 6 sets of data to evaluate. But if you switch the question around, and try to figure out what in those 94 code pushes went right, you’ll open yourself up to many more opportunities for insight.
    • A Just Culture: A just culture balances accountability with learning. No room for malice
    • Near Misses: Post mortem discussions are extremely important, and most people realize that. What’s often missed are those “near disaster” moments. Many lessons can be learned by investigating what almost went horribly wrong, and we need to have a culture that values honesty and humility to send out an email like this:

     

    • Pre Mortem: What’s better than a post-mortem is a pre-mortem! Discussing what COULD go wrong before it does. Communication is key.
    • Effective Organizational Structure: People can only be held accountable for the things that they’ve been given both the responsibility AND the authority for.

    Another fantastic talk by @allspaw!

     

  • Cory von Wallenstein 2:03 pm on June 14, 2011 Permalink | Reply
    Tags: cloud, gslb,   

    Takeaways from Netflix in the Cloud at Velocity 2011 

    Adrian Cockcroft (@adrianco) from @Netflix just gave a killer presentation at #velocityconf on their usage of the cloud in powering unprecedented growth in their business and the demands of their global infrastructure.

    To start off, you should know that Netflix is ~100% in the cloud.

    A couple key takeaways:

    Can You Build Datacenters Fast Enough?

    @adrianco led with a pretty interesting problem they faced: they could not build datacenters fast enough for their growth. Hence the “fire burning down the datacenter” slide:

    Their growth was 69% year over year, and was showing no signs of stopping. They simply could not build facilities fast enough. Not just for the serving of content (which is admittedly static… they’re just giant video files retrieved via HTTP GET), but for the re-encoding of the entire Netflix library every time a new device or platform joined the family.

    Remember when Netflix came to the Wii? The entire Netflix collection of video had to be re-encoded. Same thing for the iPad, and every other platform that now offers Netflix streaming for. They scaled out thousands of servers on-demand to meet this need.

    A Global Infrastructure Footprint

    New growth for Netflix is largely international, and they have an ambitious plan in place to capture that global demand for streaming video. Accordingly, they’re leveraging Amazon’s global footprint to put their infrastructure close to where their users are in the world. It’s a smart architectural play that increase performance for end-users and decreases the risk of downtime.

    Most of their new infrastructure will be deployed internationally, and they’re prepared and ready. When Amazon launched EC2 services in Japan, they had support in their tools for the new location and ready for production duty the next day. What was the longest delay? According to Adrian, “we had to find an icon to represent Japan in the tools!”.

    The Goals of Netflix in the Cloud

    Faster, Scalable, Available, Productive. Now those are goals we can all get on board with.

    What’s Next for Netflix in the Cloud?

    More international expansion, a larger global footprint, and pushing toward global cloud standards and commoditization of cloud computing.

    Here are the full slides:

    Overall, an outstanding kicked to #velocityconf. Well done @adrianco!

     

  • Cory von Wallenstein 10:36 am on June 7, 2011 Permalink | Reply
    Tags: confluence, gantt, kanban   

    Atlassian Summit 2011: Product Management 2.0 with Confluence 

    We’ve seen a lot of growth at Dyn Inc. recently. In the past six months alone, we’ve doubled headcount to now 80 employees. We’ve brought on board some of the biggest and most respected brands on the Internet to our Infrastructure-as-a-Service (IaaS) DNS and Email platforms. And we’ve done it without taking on outside funding.

    So what’s the secret? Well, there has been no shortage of hustle around here for starters. Just scroll through our @DynInc Twitter feed for a glimpse at the many events, product launches, performance improvements, and other kick-IaaS activities we have underway. But how can you prevent hustle from devolving into chaos at scale? How do you keep so many groups aligned in a common direction while still giving individuals the freedom they crave to have their own ideas?

    That’s where the Product Roadmap Dashboard came in. Using Confluence (the Enterprise Wiki from Atlassian) with a couple of handy open-source plugins, some good user experience design, and some ingenuity, we’ve been able to piece together something that works for us.

    I’ll be presenting the Product Roadmap Dashboard (as well as our story behind it in managing our growth and success) at Atlassian Summit 2011:

    What is the Product Roadmap Dashboard?

    The presentation is a good story on our growth pains, how Confluence helped, and how we extended Confluence to be EXACTLY what we needed. The point of this post is really for those attendees who saw the presentation and are ready to “get started”. Here I will be sharing the nitty gritty details on how it was created.

    For those unable to attend the conference, my slides are below, and I’ll post the video of the presentation as soon as it is made available (typically in a week or so).

    The Product Roadmap Dashboard is simple metadata surrounding what you likely already use Confluence for: collaboration. In addition to functional specifications, wishlists, checklists, user stories, mockups, and discussion thereof, we’re really focused on adding a few key pieces of metadata that automatically generate a “top down” view of a world that is built “bottom up.”

    All of our discussion, ideas, and thoughts ultimately get assembled into two views.

    The Kanban Chart – Visualize “flow” and “state”

    Here, we have projects color coded by platform team, that flow from left to right in the visualization through the following states:

    1. Staging – The idea bin. All the things we may want to someday do. Not shown on the dashboard, since it’s not getting active attention. It’s “pre-dashboard.”
    2. Next – We know we want to do it. Now we’re figuring out what it is, and how to do it. Writing functional and technical specifications.
    3. Active – We know what it is, we know how to do it, and now we’re executing on that plan.
    4. Finished – It’s technically complete, but we’re not “done.” We’re still wrapping up documentation (even though whatever we built is likely in production, or at least beta), we’re carefully watching logs and observing trends, we’re asking initial users for feedback, and attention is generally still being paid to this effort.
    5. Archive – We are fully complete. No additional attention is being spent on the project. Not shown on the dashboard, since it’s not getting active attention. It’s “post-dashboard.”

    The Gantt Chart – Visualize “duration” and “sequence”

    Here, we sort projects by expected due date (most recent to least recent), and show a month-level simplified Gantt chart to help folks understand at a glance the duration of projects.

    The Whole Dashboard

    If you combine these two views together, you can see in a simple dashboard where we’re going, where we currently stand, how long it will take to get to where we want to go, and in what order will we arrive at each destination.

    Getting Started: Prerequisites

    Ready to make your own Product Roadmap Dashboard in Confluence? Great! Let’s get started. You’ll need to get the following prerequisites in order first:

    You’ll want all of those plugins. Yes. All of them. They’re really useful!

    Projects, Platforms, and States – Using Labels as Metadata

    The dashboard makes extensive use of labels as metadata. There are three main categories of labels we use:

    • “project” – By having the label “project” on all pages that are relevant to be tracked in the Product Roadmap Dashboard, we have a simple way to filter out irrelevant pages later on. No variance or other values here. Just “project” as the label value.
    • Platform Team – For us, values are: “dynect” (Dynect Platform), “dyndns” (DynDNS.com), “ig” (Internet Guide), “sendlabs” (SendLabs Email Delivery), “product” (Dyn Product Team), and “operations” (Dyn Network Operations Team)
    • Project State – As mentioned in the Kanban chart above, these are the project states: “staging”, “next”, “active”, “finished”, “archive”.

    You’ll see how this assists with our assembly of the dashboard view momentarily.

    Adding New Projects – Linking Plugin and Scaffolding Plugin

    To create a new project, there are handy links included at the top of each dashboard (look for the green plus at top-left below).

    These are rendered using the add-page macro from the Linking Plugin:

    (+) {add-page:template=Project|labels=dynect,project|title=New Project|live=true|parent=Projects}Add a new Dynect Platform project{add-page}
    

    When we click on the add project link, a new page gets created based on our “Project” template. The actual content of the page will have only have the “{live-template:Project}” macro. The real work gets done by the Scaffolding Plugin using the template, discussed in the next section.

    Project Page Templates – Scaffolding Plugin

    The project template below is divided into the following sections:

    1. Quick links to important sections within the page (Details, Schedule), as well as links to all of the individual dashboards (not only the main company-wide dashboard, but focused dashboards for each platform team as well).
    2. Metadata on the two-sentence description (Overview), the team (Implementation Lead and Team Members), as well as the drop-down for the state label (Staging, Next, Active, Finished, Archived) and the expected finish date (by default, Christmas!).
    3. Wiki content with a default boilerplate for linking to children pages, attachments, as well as a table showing customers requesting the feature and the functional specifications. These are the project details. No metadata here.
    4. The Gantt chart controls. The individual radio buttons are used to set whether or not a given month shows the green dot in the Gantt style chart.
    5. Magic jQuery snippet that ensures when we change the project state using the drop-down, the previous state (remember, applied as a page label) gets removed.

    In order to set templates up in your instance of Confluence, go to the relevant space in confluence, and go to Browse -> Advanced -> Templates (you won’t see it until you have the Scaffolding Plugin installed). Create a new template called “Projects”, and paste in the below content.

    {anchor:Top}
    
    ||Quick Links|[#Project Details]|[#Project Schedule]|
    
    || Dashboards | [Dyn|Dyn Dashboard] | [Dynect|Dynect Dashboard] | [DynDNS|DynDNS Dashboard] | [IG|Internet Guide Dashboard] | [SendLabs|SendLabs Dashboard] | [Product|Product Management Dashboard] | [Operations|Operations Dashboard]
    
    || Overview | {excerpt-data:Overview|type=area|width=400px|height=100px|max-length=1000|required=true}{excerpt-data} |
    ||Implementation Lead|{list-data:Implementation Lead|required=true}{user-options:groups=engops,product}{text-sort:user:full name}{user-options}{list-data}|
    || Team Members: | {list-data:Team Members|type=check|multiple=true|required=true}{user-options:groups=engops,product,bizdev}{text-sort:user:full name}{user-options}{list-data} |
    || Current Status: | {list-data:Status}{label-options:staging,next,active,finished,archive}{list-data} |
    || Expected Finish Date: | {date-data:Finish Date|format=yyyy-MMM-dd|required=true}2011-Dec-25{date-data} ||
    
    h1. Project Details
    
    {text-data:Details|type=area|content=wiki|width=100%|height=500px|}
    h3. Quick Links
    
    {children:all=true}
    {attachments}
    
    h3. What is the feature being requested?
    
    h3. Who is requesting it?
    ||Date||Requester||Contract Size||Account Manager||Link to Request||Additional Notes||
    | | | | | | |
    
    h3. Functional specifications
    {text-data}
    
    h1. Project Schedule
    
    {metadata-list:orientation=horizontal}
    || Jan 2011 | {list-data:Jan 2011|type=check}{list-option:Y}!Icons^green-bullet.png|align=center!{list-option}{list-option:N} {list-option}{list-data} ||
    || Feb 2011 | {list-data:Feb 2011|type=check}{list-option:Y}!Icons^green-bullet.png|align=center!{list-option}{list-option:N} {list-option}{list-data} ||
    || Mar 2011 | {list-data:Mar 2011|type=check}{list-option:Y}!Icons^green-bullet.png|align=center!{list-option}{list-option:N} {list-option}{list-data} ||
    || Apr 2011 | {list-data:Apr 2011|type=check}{list-option:Y}!Icons^green-bullet.png|align=center!{list-option}{list-option:N} {list-option}{list-data}||
    || May 2011 | {list-data:May 2011|type=check}{list-option:Y}!Icons^green-bullet.png|align=center!{list-option}{list-option:N} {list-option}{list-data}||
    || Jun 2011 | {list-data:Jun 2011|type=check}{list-option:Y}!Icons^green-bullet.png|align=center!{list-option}{list-option:N} {list-option}{list-data}||
    || Jul 2011 | {list-data:Jul 2011|type=check}{list-option:Y}!Icons^green-bullet.png|align=center!{list-option}{list-option:N} {list-option}{list-data}||
    || Aug 2011 | {list-data:Aug 2011|type=check}{list-option:Y}!Icons^green-bullet.png|align=center!{list-option}{list-option:N} {list-option}{list-data}||
    || Sep 2011 | {list-data:Sep 2011|type=check}{list-option:Y}!Icons^green-bullet.png|align=center!{list-option}{list-option:N} {list-option}{list-data}||
    || Oct 2011 | {list-data:Oct 2011|type=check}{list-option:Y}!Icons^green-bullet.png|align=center!{list-option}{list-option:N} {list-option}{list-data}||
    || Nov 2011 | {list-data:Nov 2011|type=check}{list-option:Y}!Icons^green-bullet.png|align=center!{list-option}{list-option:N} {list-option}{list-data}||
    || Dec 2011 | {list-data:Dec 2011|type=check}{list-option:Y}!Icons^green-bullet.png|align=center!{list-option}{list-option:N} {list-option}{list-data}||
    {metadata-list}
    
    [!Icons^jump-top.jpg!|#Top]
    
    {jquery}
    jQuery("select[name='scaffold.Status']").change(function() {
      var labels = jQuery("input#labelsString").val();
      labels = labels.replace("staging","").replace("next","").replace("active","").replace("finished","").replace("archive","");
      jQuery("input#labelsString").val(labels);
    });
    {jquery}
    

    The Company Wide Dashboard

    The company wide dashboard aggregates the metadata stored using the templates and the Scaffolding Plugin into the view seen in the screenshots earlier. The page is divided into the following sections:

    1. Caching on the server side. Borderline requirements. The Reporting Plugin does not quickly aggregate all of this data.
    2. Links to the individual platform team dashboards
    3. The Kanban style chart, created using three columns with {section} and {column} macros, each column containing a {contentbylabel} macro that aggregates data based on page labels.
    4. Add new project links for each platform team. Done in the same manner as shown earlier using the Linking Plugin.
    5. The Gantt style chart. Created using the Reporting Plugin. Basically renders the green buttons based on whether or not that associated project page had the radio button asserted or deasserted. The {deck} and {card} macros are used to show different variants of the Gantt chart.
    6. The “Project Color Codes” template is rendered. This basically includes jQuery code that changes colors, updates icons, and makes the views shown in the above screenshots possible.
    {cache:refresh=1d|showRefresh=true|showDate=true}
    
    {anchor:top}
    
    ----
    
    {center}
    
    h1. [Projects]
    
    || Dashboards | [Dynect|Dynect Dashboard] | [DynDNS|DynDNS Dashboard] | [IG|Internet Guide Dashboard] | [SendLabs|SendLabs Dashboard] | [Product|Product Management Dashboard] | [Operations|Operations Dashboard]
    
    {composition-setup}
    
    h2. Current Dyn Inc. Projects and Efforts
    
    (Columns are sorted by page modification time, most recent to least recent)
    
    {section:border=true}
    {column} !Icons^dashboard_whats_next.png|align=center!
    {contentbylabel:label=+project,+next|showLabels=true|showSpace=false|maxResults=99|space=@self|sort=modified|reverse=true}
    {column}
    {column} !Icons^dashboard_whats_active.png|align=center!
    {contentbylabel:label=+project,+active|showLabels=true|showSpace=false|maxResults=99|space=@self|sort=modified|reverse=true}
    {column}
    {column} !Icons^dashboard_what_just_finished.png|align=center!
    {contentbylabel:label=+project,+finished|showLabels=true|showSpace=false|maxResults=99|space=@self|sort=modified|reverse=true}
    {column}
    {section}
    
    |(+) {add-page:template=Project|labels=dynect,project|title=New Project|live=true|parent=Projects}Add a new Dynect project{add-page} | (+) {add-page:template=Project|labels=dyndns,project|title=New Project|live=true|parent=Projects}Add a new DynDNS project{add-page} |(+) {add-page:template=Project|labels=ig,project|title=New Project|live=true|parent=Projects}Add a new Internet Guide project{add-page} | (+) {add-page:template=Project|labels=sendlabs,project|title=New Project|live=true|parent=Projects}Add a new SendLabs project{add-page} | (+) {add-page:template=Project|labels=product,project|title=New Project|live=true|parent=Projects}Add a new Product project{add-page} | (+) {add-page:template=Project|labels=operations,project|title=New Project|live=true|parent=Projects}Add a new Operations project{add-page} |
    
    _(On the next screen, enter in a name for the project, click Save, then provide the project details. Click Save again.)_
    
    h2. Roadmaps
    
    (Rows are sorted by expected finish date, although you can click on a column name to sort dynamically)
    
    {deck:id=projects}
    {card:label=Active Roadmap}
    {table-plus:columnTypes=S}
    
    {report-table}
    {content-reporter:types=page|labels=+active,+project}
    {date-sort:data:Finish Date|order=ascending}
    {content-reporter}
    {report-column:title=Page}{report-info:title|link=true} {html}<span class="smalltext">{html}{report-info:page:labels|separator=comma|link=true}{html}</span>{html}{report-column}
    {report-column:title=Finish Date}{get-data:name=Finish Date|format=yyyy-MM-dd}{report-column}
    {report-column:title=Apr 2011}{report-info:metadata:Apr 2011|render=wiki}{report-column}
    {report-column:title=May 2011}{report-info:metadata:May 2011|render=wiki}{report-column}
    {report-column:title=Jun 2011}{report-info:metadata:Jun 2011|render=wiki}{report-column}
    {report-column:title=Jul 2011}{report-info:metadata:Jul 2011|render=wiki}{report-column}
    {report-column:title=Aug 2011}{report-info:metadata:Aug 2011|render=wiki}{report-column}
    {report-column:title=Sep 2011}{report-info:metadata:Sep 2011|render=wiki}{report-column}
    {report-table}
    {table-plus}
    {card}
    
    {card:label=What's Next Roadmap}
    {table-plus:columnTypes=S}
    
    {report-table}
    {content-reporter:types=page|labels=+next,+project}
    {date-sort:data:Finish Date|order=ascending}
    {content-reporter}
    {report-column:title=Page}{report-info:title|link=true} {html}<span class="smalltext">{html}{report-info:page:labels|separator=comma|link=true}{html}</span>{html}{report-column}
    {report-column:title=Finish Date}{get-data:name=Finish Date|format=yyyy-MM-dd}{report-column}
    {report-column:title=Apr 2011}{report-info:metadata:Apr 2011|render=wiki}{report-column}
    {report-column:title=May 2011}{report-info:metadata:May 2011|render=wiki}{report-column}
    {report-column:title=Jun 2011}{report-info:metadata:Jun 2011|render=wiki}{report-column}
    {report-column:title=Jul 2011}{report-info:metadata:Jul 2011|render=wiki}{report-column}
    {report-column:title=Aug 2011}{report-info:metadata:Aug 2011|render=wiki}{report-column}
    {report-column:title=Sep 2011}{report-info:metadata:Sep 2011|render=wiki}{report-column}
    {report-column:title=Oct 2011}{report-info:metadata:Oct 2011|render=wiki}{report-column}
    {report-column:title=Nov 2011}{report-info:metadata:Nov 2011|render=wiki}{report-column}
    {report-column:title=Dec 2011}{report-info:metadata:Dec 2011|render=wiki}{report-column}
    {report-table}
    
    {table-plus}
    {card}
    
    {card:label=Previous Roadmap}
    {table-plus:columnTypes=S}
    
    {report-table}
    {content-reporter:types=page|labels=-staging,-next,-active,+project}
    {date-sort:data:Finish Date|order=ascending}
    {content-reporter}
    {report-column:title=Page}{report-info:title|link=true} {html}<span class="smalltext">{html}{report-info:page:labels|separator=comma|link=true}{html}</span>{html}{report-column}
    {report-column:title=Finish Date}{get-data:name=Finish Date|format=yyyy-MM-dd}{report-column}
    {report-column:title=Nov 2010}{report-info:metadata:Nov 2010|render=wiki}{report-column}
    {report-column:title=Dec 2010}{report-info:metadata:Dec 2010|render=wiki}{report-column}
    {report-column:title=Jan 2011}{report-info:metadata:Jan 2011|render=wiki}{report-column}
    {report-column:title=Feb 2011}{report-info:metadata:Feb 2011|render=wiki}{report-column}
    {report-column:title=Mar 2011}{report-info:metadata:Mar 2011|render=wiki}{report-column}
    {report-column:title=Apr 2011}{report-info:metadata:Apr 2011|render=wiki}{report-column}
    {report-table}
    
    {table-plus}
    {card}
    {deck}
    
    {center}
    
    ----
    
    {live-template:Project Color Codes}
    
    {anchor:bottom}
    
    {cache}
    

    The Individual Platform Team Dashboards

    The individual platform team dashboards are nearly identical to the company wide dashboard. The only real differences is the additional filtering based on the platform label.

    For example, if the “active” column in the  Kanban style chart in the company wide dashboard was rendered by looking at pages that have the “project” and “active” labels, then the “active” column in the Kanban style chart in the Dynect Platform specific dashboard is rendered by looking at pages that have the “project”, “active”, and “dynect” labels. Pretty simple.

    {cache:refresh=1d|showRefresh=true|showDate=true}
    
    (+) {add-page:template=Project|labels=dynect,project|title=New Project|live=true|parent=Projects}Add a new Dynect Platform project{add-page} _(On the next screen, enter in a name for the project, click Save, then provide the project details. Click Save again.)_
    
    {composition-setup}
    
    {center}
    
    h2. Current Dynect Platform Projects and Efforts
    
    {section:border=true}
    {column} !Icons^dashboard_whats_next.png|align=center!
    {contentbylabel:label=+project,+dynect,+next|showLabels=true|showSpace=false|maxResults=99|space=@self}
    {column}
    {column} !Icons^dashboard_whats_active.png|align=center!
    {contentbylabel:label=+project,+dynect,+active|showLabels=true|showSpace=false|maxResults=99|space=@self}
    {column}
    {column} !Icons^dashboard_what_just_finished.png|align=center!
    {contentbylabel:label=+project,+dynect,+finished|showLabels=true|showSpace=false|maxResults=99|space=@self}
    {column}
    {section}
    
    | {toggle-cloak:id=Change Project Status} {color:blue}_Change project status._{color} | {toggle-cloak:id=Dynect Staging} {color:blue}_View Dynect staging area for projects._{color} | {toggle-cloak:id=Dynect Archive} {color:blue}_View archived Dynect projects._{color} |
    {cloak:id=Change Project Status}
    {checklist:name=Project Status|label=dynect|parent=Projects|checklabels=staging,next,active,finished,archive}
    {cloak}
    {cloak:id=Dynect Staging}
    {report-table}
    {content-reporter:space=PDM|type=page|label=+project,+dynect,+staging}
    {text-sort:data:Priority}
    {content-reporter}
    {report-column:title=Page}{report-info:title|link=true}{report-column}
    {report-column:title=Priority}{report-info:data:Priority}{report-column}
    {report-column:title=Lead}{report-info:data:Implementation Lead|link=true}{report-column}
    {report-column:title=Team Members}{report-info:data:Team Members|link=true}{report-column}
    {report-empty}Nothing to report.{report-empty}
    {report-table}
    {cloak}
    {cloak:id=Dynect Archive}
    {report-table}
    {content-reporter:space=PDM|type=page|label=+project,+dynect,+archive}
    {text-sort:data:Priority}
    {content-reporter}
    {report-column:title=Page}{report-info:title|link=true}{report-column}
    {report-column:title=Priority}{report-info:data:Priority}{report-column}
    {report-column:title=Lead}{report-info:data:Implementation Lead|link=true}{report-column}
    {report-column:title=Team Members}{report-info:data:Team Members|link=true}{report-column}
    {report-empty}Nothing to report.{report-empty}
    {report-table}
    {cloak}
    
    h2. Roadmaps
    
    {deck:id=projects}
    {card:label=Active Roadmap}
    {table-plus:columnTypes=S}
    
    {report-table}
    {content-reporter:types=page|labels=+active,+dynect,+project}
    {date-sort:data:Finish Date|order=ascending}
    {content-reporter}
    {report-column:title=Page}{report-info:title|link=true} {html}<span class="smalltext">{html}{report-info:page:labels|separator=comma|link=true}{html}</span>{html}{report-column}
    {report-column:title=Finish Date}{get-data:name=Finish Date|format=yyyy-MM-dd}{report-column}
    {report-column:title=Apr 2011}{report-info:metadata:Apr 2011|render=wiki}{report-column}
    {report-column:title=May 2011}{report-info:metadata:May 2011|render=wiki}{report-column}
    {report-column:title=Jun 2011}{report-info:metadata:Jun 2011|render=wiki}{report-column}
    {report-column:title=Jul 2011}{report-info:metadata:Jul 2011|render=wiki}{report-column}
    {report-column:title=Aug 2011}{report-info:metadata:Aug 2011|render=wiki}{report-column}
    {report-column:title=Sep 2011}{report-info:metadata:Sep 2011|render=wiki}{report-column}
    {report-table}
    {table-plus}
    {card}
    
    {card:label=What's Next Roadmap}
    {table-plus:columnTypes=S}
    
    {report-table}
    {content-reporter:types=page|labels=+next,+dynect,+project}
    {date-sort:data:Finish Date|order=ascending}
    {content-reporter}
    {report-column:title=Page}{report-info:title|link=true} {html}<span class="smalltext">{html}{report-info:page:labels|separator=comma|link=true}{html}</span>{html}{report-column}
    {report-column:title=Finish Date}{get-data:name=Finish Date|format=yyyy-MM-dd}{report-column}
    {report-column:title=Apr 2011}{report-info:metadata:Apr 2011|render=wiki}{report-column}
    {report-column:title=May 2011}{report-info:metadata:May 2011|render=wiki}{report-column}
    {report-column:title=Jun 2011}{report-info:metadata:Jun 2011|render=wiki}{report-column}
    {report-column:title=Jul 2011}{report-info:metadata:Jul 2011|render=wiki}{report-column}
    {report-column:title=Aug 2011}{report-info:metadata:Aug 2011|render=wiki}{report-column}
    {report-column:title=Sep 2011}{report-info:metadata:Sep 2011|render=wiki}{report-column}
    {report-column:title=Oct 2011}{report-info:metadata:Oct 2011|render=wiki}{report-column}
    {report-column:title=Nov 2011}{report-info:metadata:Nov 2011|render=wiki}{report-column}
    {report-column:title=Dec 2011}{report-info:metadata:Dec 2011|render=wiki}{report-column}
    {report-table}
    
    {table-plus}
    {card}
    
    {card:label=Previous Roadmap}
    {table-plus:columnTypes=S}
    
    {report-table}
    {content-reporter:types=page|labels=-staging,-next,-active,+dynect,+project}
    {date-sort:data:Finish Date|order=ascending}
    {content-reporter}
    {report-column:title=Page}{report-info:title|link=true} {html}<span class="smalltext">{html}{report-info:page:labels|separator=comma|link=true}{html}</span>{html}{report-column}
    {report-column:title=Finish Date}{get-data:name=Finish Date|format=yyyy-MM-dd}{report-column}
    {report-column:title=Nov 2010}{report-info:metadata:Nov 2010|render=wiki}{report-column}
    {report-column:title=Dec 2010}{report-info:metadata:Dec 2010|render=wiki}{report-column}
    {report-column:title=Jan 2011}{report-info:metadata:Jan 2011|render=wiki}{report-column}
    {report-column:title=Feb 2011}{report-info:metadata:Feb 2011|render=wiki}{report-column}
    {report-column:title=Mar 2011}{report-info:metadata:Mar 2011|render=wiki}{report-column}
    {report-column:title=Apr 2011}{report-info:metadata:Apr 2011|render=wiki}{report-column}
    {report-table}
    
    {table-plus}
    {card}
    {deck}
    
    {live-template:Project Color Codes}
    
    {center}
    
    {cache}
    

    Tweaking Icons, Colors, and Display – jQuery User Macro

    Remember our fancy color coding and platform team icons? Those are accomplished with a little jQuery magic. I’ll admit, this is a dirty, nasty hack, but the visual impact makes it worth tolerating.

    To add this in, go to the relevant space in Confluence (minor limitation: I haven’t figured out how to share templates across spaces… all of the work done here was in a single “Product Management” space), and go to Browse -> Advanced -> Templates. Add a template called “Project Color Codes”, and paste in the following content:

    {jquery}
    jQuery(".smalltext").hide();
    
    jQuery("a:contains('ig')").filter(function() {return this.firstChild.nodeValue === "ig";}).parent().parent().css('background-color', '#E4F7FF');
    jQuery("a:contains('ig')").filter(function() {return this.firstChild.nodeValue === "ig";}).parent().parent().find('img').attr("src", "/download/attachments/10684251/IGIcon.gif");
    
    jQuery("a:contains('product')").filter(function() {return this.firstChild.nodeValue === "product";}).parent().parent().css('background-color', '#CCFFCC');
    jQuery("a:contains('product')").filter(function() {return this.firstChild.nodeValue === "product";}).parent().parent().find('img').attr("src", "/download/attachments/10684251/ProductIcon.gif");
    
    jQuery("a:contains('dyndns')").filter(function() {return this.firstChild.nodeValue === "dyndns";}).parent().parent().css('background-color', '#FFFFCC');
    jQuery("a:contains('dyndns')").filter(function() {return this.firstChild.nodeValue === "dyndns";}).parent().parent().find('img').attr("src", "/download/attachments/10684251/DynDNSIcon.gif");
    
    jQuery("a:contains('dynect')").filter(function() {return this.firstChild.nodeValue === "dynect";}).parent().parent().css('background-color', '#FFCC99');
    jQuery("a:contains('dynect')").filter(function() {return this.firstChild.nodeValue === "dynect";}).parent().parent().find('img').attr("src", "/download/attachments/10684251/DynectIcon.gif");
    
    jQuery("a:contains('sendlabs')").filter(function() {return this.firstChild.nodeValue === "sendlabs";}).parent().parent().css('background-color', '#ECECEC');
    jQuery("a:contains('sendlabs')").filter(function() {return this.firstChild.nodeValue === "sendlabs";}).parent().parent().find('img').attr("src", "/download/attachments/10684251/SendLabsIcon.gif");
    
    jQuery("a:contains('operations')").filter(function() {return this.firstChild.nodeValue === "operations";}).parent().parent().find('img').attr("src", "/download/attachments/10684251/OperationsIcon.gif");
    {jquery}
    

    You’ll need to do some tweaking of the above to make it work for you. Specifically, you’ll need icons that you can use for your platforms, and include the links as appropriate. If you have trouble with this portion, try downloading the Firebug plugin for Firefox, and play with the “Inspect” tool while viewing your instance of Confluence. It’s very useful for writing the jQuery selectors on what elements to alter and how to alter them.

    We keep all of the graphics for the dashboard under a single page called “Icons”. Here are the graphics, if you’d like to use them as a starting point:

    Kanban Headers


    Platform Icons

    Misc. Icons

    Server Side Caching

    You’ll notice a number of mentions of the {cache} macro in the previous examples. When you’re just getting going, I’d recommend removing this so you can iterate quickly on changes without having to clear the cache each time by clicking the refresh icon on each dashboard. However, once you’re happy with your dashboard pages, templates, and other information, re-enable it to speed up page renders. It makes a big difference.

    Need Help?

    If you need help, I can try and point you in the right direction. Leave a comment below with your questions.

     

    • Michael Gray 9:12 pm on June 15, 2011 Permalink | Reply

      Hi there,
      Great article and I have really been looking for some sort of framework to do something just like this. I think that you are using a slightly older version of confluence than we are. One of the macros, metadata list, doesn’t seem to be available anymore. So, first thing is, look out for that if you upgrade and two, I have been trying figure out exactly what it’s for. If it’s not crucial to the whole system I may not need it at all. Any thoughts n that?

    • Fabian Lopez 2:27 pm on June 24, 2011 Permalink | Reply

      Godd Job. I was in you Summit presentation. It was great, thanks for sharing this with us

    • Adolfo Casari 11:50 am on July 1, 2011 Permalink | Reply

      Hi Corey,

      I have set up this interesting approach for managing initiatives but I am running into a problem when you change the project status from the Project dashboard. The previous state label is not deleted. However when you change it in the project page with the combo box it works OK. Somehow there is a trick with the jquery code at the end of the project template that is causing this error but I can’t figure it out.

      Any ideas?

      • Cory von Wallenstein 1:02 pm on July 5, 2011 Permalink | Reply

        Hi Adolfo,

        That’s currently a limitation in the implementation. If you change from the drop down box on the actual project page, a bit of jQuery removes the old label from the page. For the checklist style views (e.g., where you apply labels using the red X’s and green checks in the table), you have to explicitly remove the old label for first.

c
compose new post
j
next post/next comment
k
previous post/previous comment
r
reply
e
edit
o
show/hide comments
t
go to top
l
go to login
h
show/hide help
esc
cancel