Migrate OpenCensus.io into HUGO Markdown Theme + Develop OpenCensus Zpages UI
Mentors: Gopi Palaniappan (Primary), Pritam Shah (Secondary), Jaana Burcu Dogan (Web Development), Yang Song (Java Development)
Application metrics and distributed traces are immensely powerful for developers, but are difficult to automatically retrieve. Based on the same technology used at Google, OpenCensus is an open source project that aims to make the collection and submission of application metrics and traces easier for developers. It gives developers the tools to track a request as it travels through each of the application services, and it helps gather any metrics of interest.
The OpenCensus Development Team and Contributors were in need of a fast and easy method to add & update their language specific sections of documentation on the OpenCensus.io website. The use of Markdown would allow them to add new pages and/or edit existing page content in plain text using any text editor. This liberates the developers and the Open Source contributing community from navigating cumbersome Markup modifications, allowing them to focus on the content quality and accuracy.
Part I, of my Proposal was to migrate the existing HTML OpenCensus.io website into a HUGO markdown theme. Prior to GSoC, I have never heard of markdown, much less know anything about the static site generator platform of HUGO. I took this task as a developing challenge and dedicated myself to quickly learn these new platforms and concepts within a short time period. During the bonding stage of the program, I studied every source of information regarding Markdown and the HUGO static site generator platform. The two topics were understandable. Straight out of the box, Hugo and markdown are simple to grasp, work with and implement. The difficulties lay in the conversion of an existing HTML built site into a HUGO platform theme.
As I mention earlier, the concept and implementation of the HUGO platform and markdown is easy to understand. At Web Development I’m a wizard, so I thought “Hey, I can do this easily.” The truth is, it took me close to 3 weeks just to capture a good understanding of the HUGO directory structure, and how to implement best practices for the initial implementation to strengthen adaptability & scalability. With the use of heavy JavaScript on the original site, I used a combination of markdown and shortcode to seamlessly render the markdown website as close to the original markup website (HTML, JScript, and CSS) as possible.
Within the site pages that relied heavly on JavaScript, I used what is called ‘Shortcode.’ Shortcodes are simple snippets inside your content files calling built-in or custom templates. Hugo created shortcodes to circumvent some limitations in markdown. Often authors are forced to use raw HTML+JScript functionality (i.e., accorddion expand/hide) within the markdown content. This contradicts the simplicity of markdown syntex. Shortcode is a code snippet inside a themes directory that Hugo will use to render a predefined template, such as HTML+JScript functionality.
In order to build the HUGO directory structure, I divided the original site into 3 primary sections.
The themes
directory will house everything related to the look and feel (template format) of the site. The content, layouts & static
directories will house everything related to the content of the site (localized format). The support
files provide needed configuration services across multiple actions, such as, estabishing the deployment pipeline - (Local repo –> Github repo –> TravisCI –> Firebase site hosting), build scripts and many more.
OpenCensus.io’s directory tree is seen below.
├── .
├── AUTHORS
├── config.toml
├── content
│ ├── about.md
│ ├── blog.md
│ ├── community.md
│ ├── cpp.md
│ ├── docs.md
│ ├── erlang.md
│ ├── explorer.md
│ ├── faq.md
│ ├── glossary.md
│ ├── go.md
│ ├── gogrpc.md
│ ├── index.md
│ ├── java.md
│ ├── overview.md
│ ├── php.md
│ ├── python.md
│ ├── roadmap.md
│ ├── ruby.md
│ ├── stats.ms
│ ├── tags.md
│ ├── traces.md
│ ├── troubleshooting.md
│ └── zpages.md
├── firebase.JSON
├── layouts
│ └── partials
│ ├── contribute.html
│ ├── footer.html
│ ├── header.html
│ ├── index_nav.html
│ ├── nav.html
│ ├── partners.html
│ ├── statsExporter.html
│ └── traceExporter.html
├── LICENSE
├── README.md
├── static
│ ├── 404.html
│ ├── api
│ │ ├── php
│ │ └── python
│ ├── css
│ │ ├── responsive.css
│ │ └── style.css
│ ├── favicon
│ ├── favicon.ico
│ ├── img
│ ├── index.html
│ ├── js
│ └── sitemap.xml
└── themes
└── census
├── archetypes
│ └── default.md
├── CHANGELOG.md
├── layouts
│ ├── _default
│ │ └── single.html
│ └── shortcodes
│ ├── go.html
│ ├── java.html
│ ├── sc_btn.html
│ ├── sc_center.html
│ ├── sc_gloss1.html
│ ├── sc_indent.html
│ ├── sc_indent1.html
│ ├── sc_indent2.html
│ ├── sc_indent3.html
│ ├── sc_indent4.html
│ ├── sc_indent5.html
│ ├── sc_indent6.html
│ ├── sc_indent7.html
│ ├── sc_indent8.html
│ ├── sc_indent9.html
│ ├── sc_indent10.html
│ ├── sc_red.html
│ ├── sc_supportedExporters.html
│ ├── sc_supportedLanguages.html
│ └── snippets.html
├── LICENSE.md
├── README.md
└── theme.toml
OpenCensus website
Landing page
OpenCensus website
Overview page
In OpenCensus, zpages implements a collection of HTML pages that display RPC stats and trace data. My task was to standardize the look and feel of the multiple zpages.
To achieve the base UI, I began work on the most complete set of Zpages built in Java. But, since OpenCensus will support multiple languages, I had to also create an external CSS of commonalities among the various zpages to be used across all languages. Basically, we need the zpages for all the supported languages to look and feel the same. To save myself from having to style each of the four zpages for every language supported, a single external CSS can achieve this, as well as, making changes in a single location very accommodating.
Some challenges I came across while working on the Zpages were the unique structures of the numerous tables used among the four Java Zpages.
Just as everyone has a distinct hand-writing style, so do programmers. I quickly learned that Open Source Development is a collaborative effort, and every contributor’s coding method is different.
Yet, another challenge I faced while styling the Zpages was how to properly implement an external resource such as a CSS using Gradle to build the resource for availability. As you can see in the snippets of code below, I was able to build the resource with Gradle, and it is available to the rpcz handler. The problem my Java mentor and I came across was determining the relative path for access to the css resource built by Gradle for live production.
Gradle build (build.gradle) lines added:
sourceSets.main.resources.srcDirs = [ "src/resources/" ]
sourceSets.main.resources.includes = [ "**/*.css" ]
Java rpcz handler lines added (hardcode direct path):
private static final String CSS_PATH =
"/Users/username/Desktop/opencensus-java" +
"/contrib/zpages/src/resources/style.css";
Java method for reading in the CSS:
private static final String STYLE;
static {
String style = "";
try {
Reader fileReader = Files.newBufferedReader(Paths.get(CSS_PATH), UTF_8);
char[] chars = new char[100000000];
fileReader.read(chars);
style = String.valueOf(chars);
} catch (Exception e) {
e.getMessage();
}
STYLE = style;
}
After a week of unsuccessful attempts at linking the Gradle build for external resources such as this CSS, JSON, JavaScript, etc., my Java mentor Yang and I resolved on a work-around. We decided to create a top-level class that hold the CSS as a string (seen below). Since this style class is part of the containing classes package package io.opencensus.contrib.zpages
, all the Zpage handlers have access to the resource.
Style.java
/* Style.java */
package io.opencensus.contrib.zpages;
final class Style {
private Style() {}
static String style =
"body{font-family: 'Roboto',sans-serif;"
+ "font-size: 14px;background-color: #F2F4EC;}"
+ "h1{color: #3D3D3D;text-align: center;margin-bottom: 20px;}"
+ "p{padding: 0 0.5em;color: #3D3D3D;}"
+ ...
+ ...;
}
This now allows the every Zpage handler access to the CSS resource.
RpcZPagehandler
/* RpcZPahehandler.java */
private static void emitStyles(PrintWriter out, Formatter formatter) {
out.write("<style>");
out.write(Style.style);
out.write("</style>");
}
Each handler now include the CSS resource in the emitStyles()
method with the addition of out.write(Style.style);
The Java access modifiers private and protected cannot be assigned to a class. Only to constructors, methods and fields inside classes. Classes can only have the default (package) and public access modifier assigned to them.
Access Modifiers | private | default | protected | public |
---|---|---|---|---|
Inside Class | Y | Y | Y | Y |
Same Package Class | N | Y | Y | Y |
Same Package Sub-Class | N | Y | Y | Y |
Other Package Class | N | N | N | Y |
Other Package Sub-Class | N | N | Y | Y |
rpczZPageHandler.java
Landing page
StatszZPageHandler.java
Stats landing page
StatszZPageHandler.java
Stats view grpc.io/server/server_latency/cumulative page
TracezZPageHandler.java
Landing page
TraceconfigzZPageHandler.java**
*Landing page
Date | Commit Description |
---|---|
Jun 10, 2018 | Rpcz, Statsz, Tracez, and Traceconfigz page styling modifications (#1295) |
Jul 24, 2018 | Zpages external CSS added and gradle modified to include this resource (#1341) |
Jul 31, 2018 | Top-level style class added for Zpages use + Final commit for GSoC… (#1351) |
Date | Event |
---|---|
Jan 4 | Mentoring organizations can begin submitting applications to Google |
Jan 23 | Mentoring organization application deadline |
Jan 23 - Feb 11 | Google program administrators review organization applications |
Feb 12 | List of accepted mentoring organizations published |
Feb 12 - Mar 12 | Potential student participants discuss application ideas with mentoring organizations |
Mar 12 | Student application period begins |
Mar 27 | Student application deadline |
Apr 23 | Accepted student proposals announced |
Apr 23 - May 14 | Community Bonding Period Students get to know mentors, read documentation, get up to speed to begin working on their projects |
May 14 | Coding officially begins! |
Jun 11 | Mentors and students can begin submitting Phase 1 evaluations |
Jun 15 | Phase 1 Evaluation deadline |
Jun 15 - Jul 9 | Work Period Students work on their project with guidance from Mentors |
Jul 9 | Mentors and students can begin submitting Phase 2 evaluations |
Jul 13 | Phase 2 Evaluation deadline |
Jul 13 - Aug 6 | Work Period Students continue working on their project with guidance from Mentors |
Aug 6 - 14 | Final week: Students submit their final work product and their final mentor evaluation |
Aug 14 - Aug 21 | Mentors submit final student evaluations |
Aug 22 | Final results of Google Summer of Code 2018 announced |
View the complete Google Summer of Code 2018 timeline.
View my complete Google Summer of Code 2018 Keynote timeline.
Prior to my participation in Google Summer of Code 2018, I had no experience with and in some cases have never heard of the platforms, programs or concepts used in Open Source Development. Things like Markdown, HUGO platform, Git and Github, TravisCI, Gradle, Google Cloud Platform, Remote Procedure Calls, Open Source & collaborative development… just to name a few, were all foreign to me. Knowing that I might struggle throughout this summer program, I chose to dive right in… in an effort to breakout of my comfort zone and commit myself to learning and adapting within a live open source ecosystem.
The first few weeks of communicating and interacting with the managers, developers and collaborators of OpenCensus was intimidating for me, to say the least. But as I continued moving forward in the program - within my contact with everyone at OpenCensus, I never felt uncomfortable asking questions or explanations.
My overall experience participating in the Google Summer of Code 2018 on OpenCensus was one of learning. GSoC has allowed me to strengthen the following skills:
I’m not much of a writer, but I will try to make this as eloquent as possible. Knowing the Google Summer of Code program is an enormous opportunity for me as a freshman developer, I placed a certain amount of pressure upon myself to achieve. Although, what I lack in “know how”, I more than make up for in determination. These 12 weeks have been stressful and challenging, yet satisfying and rewarding with the sense of accomplishment for sure.
I would like to thank my mentor Gopi Palaniappan for this opportunity. From the very start you have been my #1 supporter, having all the confidence in me to perform well. Many times we do not know how much of an impact we have on those around us. I will like to let you know, that you have made an enormous impact and influence on what I do, and where I go from here. Thank you for all the support.
I will also take this moment to thank Pritam Shah, for helping me execute a comprehensive work plan. Jaana Burcu Dogan, thank you for helping me manage the issues with the site. Yang Song, thank you for the guidance when I came across an issue that I could not resolve solo.
The generations of family members that came before me have made great sacrifices in order for me to have greater opportunities for success. There is no better way for me to repay their sacrifices, than to achieve when those opportunities are presented. My hope is that I somehow make things better for the generations who follow behind me.
- Adam Garza