Building [Security] Dashboards w/R & Shiny + shinydashboard(转)
Jay & I cover dashboards in Chapter 10 of Data-Driven Security (the book) but have barely mentioned them on the blog. That’s about to change with a new series on building dashboards using the all-new shinydashboard framework developed by RStudio. While we won’t duplicate the full content from the book, we will show different types of dashboards along with the R code used to generate them.
Why R/Shiny/shinydashboard?
You can make dashboards in a cadre of programs: from Excel to PowerPoint, Tableau to MicroStrategy (a tool of choice for the “Godfather of Dashboards” - Stephen Few), Python to Ruby, plus many canned Saas tools. shinydashboards is compelling since it:
- is completely free (unless you need or are compelled to purchase commerical support options)
- provides substantial functionality and layout options out-of-the-box
- facilitates connectivity with diverse dynamic data sources, including “big data” systems
It also enables the use of every data gathering, data munging, statistical, computational, visualization & machine-learning package R has to offer to help make your dashboards as meaningful, accurate and appealing as possible.
The shinydashboard framework is also pretty easy to wrap your head around once you dive into it. So, let’s do so right now!
Prerequisites
You’ll obviously need R, and we also recommend RStudio, especially since it has great support for developing Shiny apps.
You’ll also need the shiny and shinydashboard packages installed:
install.packages(c("devtools", "shiny"))
devtools::install_github("rstudio/shinydashboard")
We also make liberal use of the “hadleyverse” (the plethora of modern R packages created by Hadley Wickham). These include dplyr, tidyr, httr, rvest and others. Install them as you see them used/need them.
The Basic shinydashboard Framework
Shinydashboard runs on top of Shiny, and Shiny is an R package that presents a web front-end to back-end R processing. All Shiny apps define user-facing components (usually in a file called ui.R) and server-side processing components (usually in a file called server.R) and usereactive expressions to tie user actions (or timed triggers) to server events (or have server-side events change the user-interface). Shiny applications present themselves in a Bootstrap 3template and the shinydashboard package adds a further layer of abstraction, making it fairly simple to embed complex controls and visualizations without knowing (virtually) any HTML.
When building shinydashboards, you work with:
- header components (titles, notificaitons, tasks & messages)
- sidebar components (menus, links, input components)
- main dashboard body (composed of “boxes”)

The following is the R version of that structure in a single-file shinydashboard app (app.R) without any extra components:
library(shiny)
library(shinydashboard) # Simple header ----------------------------------------------------------- header <- dashboardHeader(title="CYBER Dashboard") # No sidebar -------------------------------------------------------------- sidebar <- dashboardSidebar() # Compose dashboard body -------------------------------------------------- body <- dashboardBody(
fluidPage(
fluidRow()
)
) # Setup Shiny app UI components ------------------------------------------- ui <- dashboardPage(header, sidebar, body, skin="black") # Setup Shiny app back-end components ------------------------------------- server <- function(input, output) { } # Render Shiny app -------------------------------------------------------- shinyApp(ui, server)
If you’re wondering what’s up with the long “
# xyz ---” comments, RStudio will use them to provide block entries in the source code function navigation menu, making it really easy to find sections of code quite quickly.
Paste that into an RStudio file pane and source (run) it to see how it works (we’ll cover using it in the context of a Shiny server environment in another post).
Building a ‘Con’ Board
We infosec folk seem to really like “Con” (“current threat level”) gauges. We’ve got the SANSISC “Infocon”, Symantec’s “ThreatCon” and IBM X-Force’s “AlertCon” (to name just a few). Let’s build a dashboard that grabs the current “Con” status from each of those three places and puts them all into one place.
It’s always good to start with a wireframe layout for your dashboard (even though this is a pretty trivial one). Let’s have one row of shinydashboard valueBoxes:

which will normalize the look & feel of the alerts, and make a tap/select on each box take the user to the actual alert site for more details.
Since we’re going to be parsing JSON and HTML from various places, we’ll be making liberal use of the hadleyverse and some other packages:
library(shiny)
library(shinydashboard)
library(httr)
library(jsonlite)
library(data.table)
library(dplyr)
library(rvest)
library(magrittr)
The initial setup code looks the same as the basic example above, but it adds some elements to the fluidRow to give us places for our status boxes:
header <- dashboardHeader(title="CYBER Dashboard") sidebar <- dashboardSidebar() body <- dashboardBody(
fluidPage(
fluidRow(
a(href="http://isc.sans.org/",
target="_blank", uiOutput("infocon")),
a(href="http://www.symantec.com/security_response/threatcon/",
target="_blank", uiOutput("threatcon")),
a(href="http://webapp.iss.net/gtoc/",
target="_blank", uiOutput("alertcon"))
)
)
) ui <- dashboardPage(header, sidebar, body, skin="black")
Now, in the server function, we have three sections, each performing data gathering, extraction and placement in the valueBoxes. We start with the easiest, the SANS ISC Infocon:
server <- function(input, output) {
output$infocon <- renderUI({
infocon_url <- "https://isc.sans.edu/api/infocon?json"
infocon <- fromJSON(content(GET(infocon_url)))
valueBox(
value="Yellow",
subtitle="SANS Infocon",
icon=icon("bullseye"),
color=ifelse(infocon$status=="test", "blue", infocon$status)
)
})
The output$infocon is tied to the uiOutput("infocon") in the dashboardBody and the setup code grabs the JSON from the DSheild API and ensures the right color and label is used for thevalueBox (I’m not entirely thrilled with the built-in color choices, but they can be customzed through CSS settings and we’ll cover that in a later post, too).
The remaning two section require finding the right HTML tags and extracting the con status from it, then tying the level to the right color. I use both CSS & XPath selectors in the following examples just to show how flexible the rvest package is (and I am a recoveringXML/XSLT/XPath user):
output$threatcon <- renderUI({
pg <- html("http://www.symantec.com/security_response/#")
pg %>%
html_nodes("div.colContentThreatCon > a") %>%
html_text() %>%
extract(1) -> threatcon_text
tcon_map <- c("green", "yellow", "orange", "red")
names(tcon_map) <- c("Level 1", "Level 2", "Level 3", "Level 4")
threatcon_color <- unname(tcon_map[gsub(":.*$", "", threatcon_text)])
threatcon_text <- gsub("^.*:", "", threatcon_text)
valueBox(
value=threatcon_text,
subtitle="Symantec ThreatCon",
icon=icon("tachometer"),
color=threatcon_color
)
})
output$alertcon <- renderUI({
pg <- html("http://xforce.iss.net/")
pg %>%
html_nodes(xpath="//td[@class='newsevents']/p") %>%
html_text() %>%
gsub(" -.*$", "", .) -> alertcon_text
acon_map <- c("green", "blue", "yellow", "red")
names(acon_map) <- c("AlertCon 1", "AlertCon 2", "AlertCon 3", "AlertCon 4")
alertcon_color <- unname(acon_map[alertcon_text])
valueBox(
value=alertcon_text,
subtitle="IBM X-Force",
icon=icon("warning"),
color=alertcon_color
)
})
}
shinyApp(ui, server)
The result is a consistent themed set of internet situational awareness at a high level:

OK, I snuck some extra elements in on that screen capture, mostly as a hint of things to come. The core elements - the three “con” status boxes are unchanged from the simple example presented here.
You can find the code for the dashboard in this gist and you can even take a quick view of it (provided you’ve got the required packages installed) viashiny::runGist("e9e941ad4e3568f98faf"). As a general rule, I advise either running code locally (after inspection) or carefully examining the remote code first before blindly running foreign URLs. This is the R equivalent of curl http://example.com/script.sh | sh, which is also abad practice (unless it’s your own code).
Next Steps
The dashboard in this post loads all the data dynamically, but only once. In the next post, we’ll show you how to incorporate more data elements, incorporate dynamic updating capabilities and also add some other sections to the dashboard, including sidebar menus and header notifications.
Building [Security] Dashboards w/R & Shiny + shinydashboard(转)的更多相关文章
- R Shiny app | 交互式网页开发
网页开发,尤其是交互式动态网页的开发,是有一定门槛的,如果你有一定的R基础,又不想过深的接触PHP和MySQL,那R的shiny就是一个不错的选择. 现在R shiny配合R在统计分析上的优势,可以做 ...
- R shiny 小工具Windows本地打包部署
目录 服务器部署简介 windows打包部署 1. 部署基本框架 2.安装shiny脚本需要的依赖包 3.创建运行shiny的程序 [报错解决]无法定位程序输入点EXTPTE_PTR于动态链接库 将小 ...
- e.g. i.e. etc. et al. w.r.t. i.i.d.英文论文中的缩写语
e.g. i.e. etc. et al. w.r.t. i.i.d. 用法:, e.g., || , i.e., || , etc. || et al., || w.r.t. || i.i.d. e ...
- 将Shiny APP搭建为独立的桌面可执行程序 - Deploying R shiny app as a standalone application
目录 起源! 目的? 怎么做? 0 准备工作 1 下载安装R-portable 2 配置 Rstudio 3 搭建Shiny App 3.1 添加模块 3.2 写AppUI和AppServer 3.3 ...
- R︱shiny实现交互式界面布置与搭建(案例讲解+学习笔记)
要学的东西太多,无笔记不能学~~ 欢迎关注公众号,一起分享学习笔记,记录每一颗"贝壳"~ --------------------------- 看了看往期的博客,这个话题竟然是第 ...
- kmeans聚类中的坑 基于R shiny 可交互的展示
龙君蛋君 2015年5月24日 1.背景介绍 最近公司在用R 建模,老板要求用shiny 展示结果,建模的过程中用到诸如kmean聚类,时间序列分析等方法.由于之前看过一篇讨论kmenas聚类针对某一 ...
- Python文件的四种读写方式——r a w r+
# 文件的基本操作,但是一般不这么使用,因为经常会忘记关闭 password=open("abc.txt",mode="r",encoding="UT ...
- 文件操作:w,w+,r,r+,a,wb,rb
1.文件操作是什么? 操作文件: f = open("文件路径",mode="模式",encoding="编码") open() # 调用操 ...
- python open函数关于w+ r+ 读写操作的理解(转)
r 只能读 (带r的文件必须先存在)r+ 可读可写 不会创建不存在的文件.如果直接写文件,则从顶部开始写,覆盖之前此位置的内容,如果先读后写,则会在文件最后追加内容.w+ 可读可写 如果文件存在 则覆 ...
随机推荐
- jQuery小测的总结
1.在div元素中,包含了一个<span>元素,通过has选择器获取<div>元素中的<span>元素的语法是? 提示使用has() 答案: $(div:has(s ...
- .Net 官方学习文档
.Net 官方学习文档:https://docs.microsoft.com/zh-cn/dotnet/articles/welcome
- Spring+IOC(DI)+AOP概念及优缺点
Spring pring是一个轻量级的DI和AOP容器框架. 说它轻量级有一大部分原因是相对与EJB的(虽然本人从没有接触过EJB的应用),重要的是,Spring是非侵入式的,基于spring开发的应 ...
- tcp并发服务端
TCP并发服务器:并发服务器的思想是每一个客户端的请求并不由服务器的主进程直接处理,而是服务器主进程创建一个子进程来处理. 创建TCP并发服务器的算法如下: socket(……): //创建一个TCP ...
- (函数封装)获取class名称
使用原生JavaScript,获取类操作符时:即使使用getElementByClassName,在Firefox和IE9以下是不兼容的.Firefox下是可以用它获取的到元素而IE不行,一般框架都会 ...
- python自动化开发-[第一天]-基础数据类型与编码
1.Python与其他语言对比 - C语言的解释方式 代码-->机器码-->计算机 - python,java,php等高级语言的解释方式 代码-->字节码-->机器码-- ...
- wcf发布的服务在前端调用时,遇到跨域问题的解决方案
我是使用IIS作为服务的宿主,因此需要在web.config中增加如下配置节: <bindings> <webHttpBinding> <binding name=&qu ...
- 蓝桥杯-打印大X-java
/* (程序头部注释开始) * 程序的版权和版本声明部分 * Copyright (c) 2016, 广州科技贸易职业学院信息工程系学生 * All rights reserved. * 文件名称: ...
- 蓝桥杯-买不到的数目-java
/* (程序头部注释开始) * 程序的版权和版本声明部分 * Copyright (c) 2016, 广州科技贸易职业学院信息工程系学生 * All rights reserved. * 文件名称: ...
- poj2349,最小生成树!
The Department of National Defence (DND) wishes to connect several northern outposts by a wireless n ...