Building Custom Analytics Dashboards with Cloudflare Data and Ruby Gems

Recent Posts

𝑭𝒓𝒂𝒏𝒄𝒆𝒍𝒍𝒂 𝑳𝒐𝒑𝒆𝒛💗 tellomaryuri.07 MARYURI soyisabela69 ISABELA 💜 tharealkilani KILANI👑 kathykourtney Kourtney 🌸🫧✨ mayaazevedo.7 Maya🍓 maduazevedof Maria eduarda Azevedo sahara.perez s a h a r a shantalbaby19 Shantal Divanecci genesismuneton.oficial Genesis Muñeton diana.losangeles Soy Diana 😊 dania.mndzfans Dania Mendez Fans adrianaolivare2 Adriana Nicolle nashlyguerrero05 𝒊𝒕𝒔.𝒌𝒂𝒓𝒊𝒏𝒂 orianafalla Oriana Falla🌟 gilaryechavarria •Gilary☀️• paradicemodels paradicemodels maryladulcy Mari Dulcy sayguz Saray Guzmán florsita.20 Florsita 🌺 hotkingandqueenofc Mauricio Perez Pereira sebaspuentes18 Sebastian Puentes m3liimtx Melissa yinethfit Yineth Medina paygeblog Paygeblog mayleediazmejia M A Y L E E D I A Z jissrivera idalipau Pau Espinoza samantagom Samanta Gomez natthalygamezr Natthaly Gámez crystalchamorroof Crystal Chamorro maytejuarezm Mayté isalocu I S A B E L L A L Ó P E Z chiquin Gabriela chiquin carotrespalaciosg Caro Trespalacios katherineburgosr Kathy Isabella serenagarciaz Serena Garcia meshh25 Cindy Valladares adac1.of Angelica Armenta C. lisbeeeethh Lisbeth Vega itsokayl.a Kayla Rose hadesalmaa Salmahades daniaab252 Daniela Albornoz viickmoranguinhoo Vitória Souza Claudes karenfeaz2 Karen Azevedo bbsants11 bbsants jailyneojeda Jailyne Ojeda Ochoa veronica.rose.xo Veronica Rose vivilomelin Viviané Lomelin 🤍 angiebrand.ofi Angie Brand 👑 iamangiebrand segui angie 😍 dayanacarolinavd Dayana Vargas cervoluz Luz Celina Cervo isa.giraldo03 Isabela Giraldo rosaflopes Rosa Furtado Lopes vickmarise01 Vitória Marise vanessavc03 Vanessa Vargas Castaño brunaalvesfc Bruna Alves brendapereiraofc 𝐁𝐫𝐞𝐧𝐝𝐢𝐧𝐡𝐚 barragandavila Yennifer Andrea ❤️‍🔥 michellegiraldoreels MICHELLE GIRALDO laurarios1229 Laura Ríos samanthamg nvthaii ꓕɥɐ¡ adrianaolivarezx Adriana OlivarezFans soymalegonzalez Male Gonzalez karolsojoo Karol Sojo mary.alvrz.7 Mary Álvarez hellennfonsecaa Hellen Fonseca Kawaguishi paulabaletaof Paula Baleta gisellemontesreels Giselle montes reels globalmodels.1 Global Models barbiegolosareels Barbie golosa🐰 barbiegolosatv LaBarbieGolosa 🍭 barbiegolosaclips Barbie golosa🐰🍭 labarbiegolosa Barbie🐰 mariaelisa.barbie Maria Elisa gioisartsy Giorgia🩵 barbiemexy Barbie Mexy marshmallowzaraa Zara 😇 genesisparram Genesis Parra adrianaolivarezof Jada adriana olivarez 1wingirls 1win Girls bbruth Ruth glxy72 reserva.dib GIOVANA DIB iaraqq iaraam kayla.sky.w Sky Kayla ❣️ cassidybaileyfitness Cassidy Bailey | Orlando Trainer 🤸🏼‍♀️ hannahgoldy Hannah “24K” Goldy acvi1777 ana🤍 provincia.1330 💎RD😍 babeeeluuu Babe Luuu🧸 kattmont Katt Mont adabntz Ada Benitez tiobang2.0 TIOBANG 2.0 quezia.fernandes2 𝑸𝒖𝒆́𝒛𝒊𝒂 𝑭𝒆𝒓𝒏𝒂𝒏𝒅𝒆𝒔 bellagirllyy onlyalexar Alexa Roman jocessitaoficial Jocelyn Macias andreacastro1x Andrea Castro labiosrojosjs Labios Rojos velourbag Velour|Carteras velouresport VELOUR SPORT ® Ropa deportiva | Activewear kelly.sweetiee 𝓚𝓔𝓛𝓛𝓨 𝓢𝓦𝓔𝓔𝓣𝓘𝓔𝓔🍬 alimarosee Alima Rosee serranolaura26 Laura Serrano Sánchez ✨ katherine.mendoza1 Kathe Mendoza anittamillerr Anitta katherine.mendoza2 Katherine.mendoza2 teenrack ribeiromarioficial femmecanela Femme Canela viralwomansofficial Viral Womens Official 🙊🌎💁🏻‍♀️💁🏼‍♀️ fleekbaez fleekbaez ellensallesreal Ellen sofiacoste95 Sofía Coste 👩🏻‍🏫 camilanonatto Camila Nonato | Influencer 🦋 vhaleryreina Vhalery Reina vhaleryjrcof Vhalery Reina julianebelo Juliane belo✨ jennifermontnegro Jennifer Deniz mariiam.hdzz mariam Desiree Hernández longhairmodelz Long Hair Modelz biancabitt4 Bianca souza kagan.yasarr89 imgmodels0 ImgModels thelions35 TheLions joxmkaliii halimacuttey1 wildlyher1 her callme.lissa sofiaglow12 sofi lindabeut7 lilyqueen1 lilyyqueeen lunavibes.2 luna mercadomiisla Daniela Martinez Asia sonicruz1 SONI CRUZ | lauradoll925 Laurita joyy.mei Joy Mei natipermu Nati Perdomo📸🎥🎞🎬🎭 certifiedlovergirll1 Ardena lunaa.michell Luna michel karlamuentes05 Karla Muentes ela.nandaa Fernanda Silva elymarmusic Elymar Zurita merymaynezz ℳ𝑒𝑒𝓇 ltsrosita celineabdallahh Celine steffymoreno551 Estefanía Moreno castillomariape Maria Paula 🦋 sophielawre jullzss Jullz matamoros kkkkattt.t 𓃠 jverazo Alizze cronikia CronikIA jane202544 เจน เกียมือ aryceldagonzalex Arycelda yourbluebeari3 Blue 🎀 sabrinaandreina09 Migdanyela Carolina Pineda maydeline.m01 Maydeline🩷 melanyphs Melany hernandez katalinareels Diana catalina rivasgabriela Gabriela Rivas katherinegonzales1 Katherine Gonzalez lamo.rena779 La Morena misaelacastejon Misaela castejon pd.beamm ଈ ᗷeᗩᗰ 🥩 imdenisesserena Denise Serena neemsaybby lauradoll925 Laurita jassminabrego 𝓙𝓪𝓼𝓼𝓶𝓲𝓷 𝓪𝓫𝓻𝓮𝓰𝓸 🖤 jasjasminka Таїсія Стаценко heyitsl11 Lucy Perez elizaamejia Eliza stefyquiroz1 Stefy Quiroz ramonaenriquezof48 Ramona 🍍 marleny1 👩‍🏫La maestra jpalacios11 Y U L I 🌸 secretvikelsik Wika Boszczar andyysgtc Angiesuz itzzoeyava Zoey 🤍 sayusos Miss Sosita 💗 victoriaashows Victoria Shows❣️ iamnamaari Namaari realnancyhernandez Nancy Hernandez nicolrojasd3 Nicol Rojas foncechichi yuliett.torres Yuliett Torres 💋 ysaaa Ysabel Reyes denisskimberly Deniss mei.cornejo Michelle Cornejo eduardaazevdo07 eduarda Azevedo fmccmodells FMC Models juliana.chapeta Juliana Chapeta elibyth1997 Eliby1997 damarismung2024 Damaris anaaa25 Ana Ladino andreaturcios2000 Andrea Turcios valeryaltamar001 Valery Altamar lucianalunareels Luciana Marin dearfranch Dearfranch cx9lz Mram Al-Ali evleenshaxma 🫦adult page 🥵 elsalvadorxd503 Elsalvadorxd 💃🇸🇻 jessicapalacios.1 Jessica Palacios soficastroof R. Milagros Orona lakress2 Lakress valvnsx valery🧸 masdejulissa Julissa Gonzalez 🇲🇽 sharmila.sharmaaa Sharmila lorenagcol Lorena Garzon angeline.peach Angeline danielagamez19 Monica 🌴 julissaventurasv Julissa Ventura amandapaolagomez amanda paola gomez orozco stephazapata6 𝓢 💗 eclipsenuria eclipse.nuria romiladyflex Romi adyolivarezof Jada adriana olivarez lavaliii Marisol Navarro 💨 cuteelf03 CutEe Elf portsbeautiful Ports Beautiful alliebabyx Alexandria Vega carolinariverag1 Carolina Rivera Gallo mimizinhaofficial Mimi Official🥰 slayedprettybysi Pretty Si💕 valeriacastrillonb VALERIA CASTRILLÓN. amothaisita Thais 🙈 duualupitaa DUALUPITA angiecastellon2 Sari✨ claritza.martinez.399 Claritza Martinez damamungui Damaris Munguia liahdz Lianet Hernández hairbyhatem HATEM KASSEM guanaquita01 Noely mariasalazara Maria Jose Salazar deisynunez01 Deisy nuñez darlinspb Darina Smychkova madelineguarda2 Madeline Guardado johanareaof Johana jucamarrgo 𝚓𝚞𝚕𝚒𝚊 𝚌𝚊𝚖𝚊𝚛𝚐𝚘 wendyhernandezsv Wendy Hernández joserojas.1 Jose De La Rosa soloriell Kari taveras larahsantosofc Larah Santos realcarmencuevas Carmen Cuevas layani19790 Layani Rosales anitta.cortez Erika Smil notasdeanaid Notas de Anaid stefannix97 Curvy | Stefanni anagabync Mariangela Nieves ysmara011 Ysmara011 shayoficiall Shayanne Dias ✨ sunnyrayyxo ♡ Sunny ♡ clickhere Flexi Tatii heycarmensita Carmensita Cuevas auragirls02 jannet🐝 soydaneyis Daneyis oumaymaelmaate1 Oumayma El Maate soyjoha888 joha giraldo taniaimarl3 TANIA MARTINEZ ✨ angnoriega Angel Noriega sophia.05 SOPHIA CORREA phylimelo Daiane Pompilio | Cabelo • Penteados • Dicas bianquicristal Bianca zanetti vi.hairlab VI | HAIR LAB. yenlachinita Yenni Godoy fanyypalacioss Fanny Palacios babyl2690 BabyL sharmasaksh Sakshi Sharma Gujral lavidadejulissa Julissa Gonzalez 🫶🏻 kattherin99 Katherine Magaña🌙 official.yaha Yahara Fernández realadrianarios Adriana Rios cristylazo Cristyy L. dannalia.cg Dannalía Camarillo kkenzimay Ms. May dianacalderontv Diana Calderón marii.marii.24 Maria Q erikaguardado.sv Erika Guardado karlycatrachita09 Karla verdejo arlynabreuu Arlyn deicythabenitez DEICY BENITES taylerhillss Tayler hills perlitaapena Perla Peña jennymadura JENN HERNÁNDEZ yoaecheverri Yoa Echeverri sindybarrientos9 Sindy Barrientos perezcandy perezcandy luisaprietog Luisa Prieto G | Modelo | Ugc sammythighsreels Sammy Thighs liliaanmorales Lilian Morales sabinaalexiia Sabina Alexia kescobar1015 Karen Garcia aleyoeramirez Ale Yoe Ramirez belengof Belén G laqueenscobr Pazita Escobar natyycardonaa Nathaly Cardona meibelynramirezz Meibelynn🦋 duniasantosurbina Dunia Santos belkisnunez06 Belkis nunez salmaflores23 Salma flores michellegaleanog 𝓜𝓲𝓬𝓱𝓮𝓵𝓵𝓮 𝓖𝓪𝓵𝓮𝓪𝓷𝓸 𝓖𝓲𝓻𝓪𝓵𝓭𝓸 beautiesreelss yesenia870 Yesenia Garcia s.arce01 𝒮𝓉𝑒𝓅𝒽𝒶𝓃𝓎 𝒶𝓇𝒸𝑒 👸🏻 mithaiofficial3349 Mithai Poly realsjc Stephanie Collier nayibbukele Nayib Bukele soniieta Sonia Salcedo Espinar kimyleveron Katherine Leveron♥ angiekatherine julsgoes Juls Pérez ♡ Guatemala ↠ Travel soy.lunacutee Luna ✌️ wangfeng1055 王风 sachellsmit 🌸Zuleima barbiefernandez Bárbara Fernández🫧 gutiierrez Kassandra soyashleycarolina Mirbelys Pineda estefanyguzman2000 Estefany Guzmán yosselinbriceno Yosselin Briceño dimevaluu theangelinepeach Angeline Cleon maferrsalinas M A F E R S A L I N A S 🇸🇻📍 eleonorvilleda Eleonor Villeda dianaescachaita Diana Galindo yaritzalopez88 Yaritza Lopez almariamx Almariamx adalizlatorre Adaliz Latorre Melendez sandra.blandonv Sandra M. Blandón Velez mabelo.0 Mabel Alonzo 🙃 biancasantiago00 Vanessa Santiago. carmennnof Carmen daisyroddriguez Daisy Rodriguez nicolleolliveira Nicole Oliveira nikkilugoo Nikki Lugo natyycardonaaaa NATYNATACHA spoilerfromparis Virals lareynaescobar Rosse Escobar stunnergirlsx Stunnergirls🦋 lovely.franco1 Yamileth.franco paulette10787 Paulina Amaya mariaisabelb11 Maria Isabel Benitez luizagomesmd Luiza Gomes gellybea29 Gelly Bea Isorena bonjoursv Bonjour ® ropa, accesorios kareliimadura Karla contreras abigaiil.morrisfanpag Abigaiil Morris Fanpage 1x.sanu ❓ manuelagudelo Manuela Agudelo glorielamx Gloriela Mx asmaeelbachari Asmae EL Bachari debyy.marantika Nona Debyy paulett250 Angela amaya mandysp.winx Mandy Winx julyssagarciav Julyssa Garcia torresmtorres7 Wendy Torres cakebunnies Cake Bunnies emilyhairexpert Emily Guadalupe Canales exitooficial Exito San Miguel leticiadisher Leticia Disher Vieira angiebeltran9 ANGIE BELTRAN yurianpoficial Yurianpoficial erinenfermera Erin Garcia smartcell.eirl 𝕊𝕠𝕞𝕠𝕤 𝕥𝕦 𝕞𝕖𝕛𝕠𝕣 𝕠𝕡𝕔𝕚ó𝕟 lachicadelcoco La Chica Del Coco stephjc Stephanie Collier monicavallejjo Monica Vallejo elaine.faleiros Elaine Faleiros pellondsv PELLONDSV soyjoaaaa Joa stylebyanna Anna🦄 wichitosv Kike Argueta zoilasanchezsanchez Zoila Yesenia Sanchez Sanchez cosviickye Cosvickye mimibolivianaofc Mimi boliviana scarlettarafat Scarlett🌸 carol.ashle122 Carolina Pineda lapresion1889 Lapresion1889 doctorasindyorellanasv Doctora Sindy Orellana. sweetmartinaponce Martina villacisnattalya09 Nataly villacis zineb.jr77 Zineb.jr7 abi107w Abigail alebernal Alejandra Bernal lilia0903 Lilia Martinez daalahi Dalahi Delgado elenavillatorotv Elena Villatoro saraitejada04 Sarai Gomez rosaliacarrasco Rosalia Carrasco yurypenaranda Yury karina peñaranda Sánchez dayidenisse24 Dayi alvarez yanitza01 Turcios💕 luisafeliperamirez Luisa Felipe mtcuadrado Maria Teresa Cuadrado ♥️ Motivación rosaliamaestra Rosalíamaestra anyadhina anyadhina ms.sethii Shilpa Sethi adrylababy

Cloudflare Analytics gives you data, but the default dashboard is limited. You can't combine metrics from different time periods, create custom visualizations, or correlate traffic with business events. You're stuck with predefined charts and can't build the specific insights you need. This limitation prevents you from truly understanding your audience and making data-driven decisions. The solution is building custom dashboards using Cloudflare's API and Ruby's rich visualization ecosystem.

Designing a Custom Dashboard Architecture

Building effective dashboards requires thoughtful architecture. Your dashboard should serve different stakeholders: content creators need traffic insights, developers need performance metrics, and business owners need conversion data. Each needs different visualizations and data granularity.

The architecture has three layers: data collection (Cloudflare API + Ruby scripts), data processing (ETL pipelines in Ruby), and visualization (web interface or static reports). Data flows from Cloudflare to your processing scripts, which transform and aggregate it, then to visualization components that present it. This separation allows you to change visualizations without affecting data collection, and to add new data sources easily.

Dashboard Component Architecture

Component Technology Purpose Update Frequency
Data Collection Cloudflare API + ruby-cloudflare gem Fetch raw metrics from Cloudflare Real-time to hourly
Data Storage SQLite/Redis + sequel gem Store historical data for trends On collection
Data Processing Ruby scripts + daru gem Calculate derived metrics, aggregates On demand or scheduled
Visualization Chartkick + sinatra/rails Render charts and graphs On page load
Presentation HTML/CSS + bootstrap User interface and layout Static

Extracting Data from Cloudflare API

Cloudflare's GraphQL Analytics API provides comprehensive data. Use the `cloudflare` gem:

gem 'cloudflare'

# Configure client
cf = Cloudflare.connect(
  email: ENV['CLOUDFLARE_EMAIL'],
  key: ENV['CLOUDFLARE_API_KEY']
)

# Fetch zone analytics
def fetch_zone_analytics(start_time, end_time, metrics, dimensions = [])
  query = {
    query: "
      query {
        viewer {
          zones(filter: {zoneTag: \"#{ENV['CLOUDFLARE_ZONE_ID']}\"}) {
            httpRequests1mGroups(
              limit: 10000,
              filter: {
                datetime_geq: \"#{start_time}\",
                datetime_leq: \"#{end_time}\"
              },
              orderBy: [datetime_ASC],
              #{dimensions.any? ? "dimensions: #{dimensions}," : ""}
            ) {
              dimensions {
                #{dimensions.join("\n")}
              }
              sum {
                #{metrics.join("\n")}
              }
              dimensions {
                datetime
              }
            }
          }
        }
      }
    "
  }
  
  cf.graphql.post(query)
end

# Common metrics and dimensions
METRICS = [
  'visits',
  'pageViews',
  'requests',
  'bytes',
  'cachedBytes',
  'cachedRequests',
  'threats',
  'countryMap { bytes, requests, clientCountryName }'
]

DIMENSIONS = [
  'clientCountryName',
  'clientRequestPath',
  'clientDeviceType',
  'clientBrowserName',
  'originResponseStatus'
]

Create a data collector service:

# lib/data_collector.rb
class DataCollector
  def self.collect_hourly_metrics
    end_time = Time.now.utc
    start_time = end_time - 3600
    
    data = fetch_zone_analytics(
      start_time.iso8601,
      end_time.iso8601,
      METRICS,
      ['clientCountryName', 'clientRequestPath']
    )
    
    # Store in database
    store_in_database(data, 'hourly_metrics')
    
    # Calculate aggregates
    calculate_aggregates(data)
  end
  
  def self.store_in_database(data, table)
    DB[table].insert(
      collected_at: Time.now,
      data: Sequel.pg_json(data),
      period_start: start_time,
      period_end: end_time
    )
  end
  
  def self.calculate_aggregates(data)
    # Calculate traffic by country
    by_country = data.group_by { |d| d['dimensions']['clientCountryName'] }
    
    # Calculate top pages
    by_page = data.group_by { |d| d['dimensions']['clientRequestPath'] }
    
    # Store aggregates
    DB[:aggregates].insert(
      calculated_at: Time.now,
      top_countries: Sequel.pg_json(top_10(by_country)),
      top_pages: Sequel.pg_json(top_10(by_page)),
      total_visits: data.sum { |d| d['sum']['visits'] }
    )
  end
end

# Run every hour
DataCollector.collect_hourly_metrics

Ruby Gems for Data Visualization

Choose gems based on your needs:

1. chartkick - Easy Charts

gem 'chartkick'

# Simple usage
<%= line_chart Visit.group_by_day(:created_at).count %>
<%= pie_chart Visit.group(:country).count %>
<%= column_chart PageView.group(:browser).count %>

# With Cloudflare data
def traffic_over_time_chart
  data = DB[:hourly_metrics].select(
    Sequel.lit("DATE_TRUNC('hour', period_start) as hour"),
    Sequel.lit("SUM((data->>'visits')::int) as visits")
  ).group(:hour).order(:hour).last(48)
  
  line_chart data.map { |r| [r[:hour], r[:visits]] }
end

2. gruff - Server-side Image Charts

gem 'gruff'

# Create charts as images
def create_traffic_chart_image
  g = Gruff::Line.new
  g.title = 'Traffic Last 7 Days'
  
  # Add data
  g.data('Visits', visits_last_7_days)
  g.data('Pageviews', pageviews_last_7_days)
  
  # Customize
  g.labels = date_labels_for_last_7_days
  g.theme = {
    colors: ['#ff9900', '#3366cc'],
    marker_color: '#aaa',
    font_color: 'black',
    background_colors: 'white'
  }
  
  # Write to file
  g.write('public/images/traffic_chart.png')
end

3. daru - Data Analysis and Visualization

gem 'daru'
gem 'daru-view'  # For visualization

# Load Cloudflare data into dataframe
df = Daru::DataFrame.from_csv('cloudflare_data.csv')

# Analyze
daily_traffic = df.group_by([:date]).aggregate(visits: :sum, pageviews: :sum)

# Create visualization
Daru::View::Plot.new(
  daily_traffic[:visits],
  type: :line,
  title: 'Daily Traffic'
).show

4. rails-charts - For Rails-like Applications

gem 'rails-charts'

# Even without Rails
class DashboardController
  def index
    @charts = {
      traffic: RailsCharts::LineChart.new(
        traffic_data,
        title: 'Traffic Trends',
        height: 300
      ),
      sources: RailsCharts::PieChart.new(
        source_data,
        title: 'Traffic Sources'
      )
    }
  end
end

Building Real Time Dashboards

Create dashboards that update in real-time:

Option 1: Sinatra + Server-Sent Events

# app.rb
require 'sinatra'
require 'json'
require 'cloudflare'

get '/dashboard' do
  erb :dashboard
end

get '/stream' do
  content_type 'text/event-stream'
  
  stream do |out|
    loop do
      # Fetch latest data
      data = fetch_realtime_metrics
      
      # Send as SSE
      out   "data: #{data.to_json}\n\n"
      
      sleep 30  # Update every 30 seconds
    end
  end
end

# JavaScript in dashboard
const eventSource = new EventSource('/stream');
eventSource.onmessage = (event) => {
  const data = JSON.parse(event.data);
  updateCharts(data);
};

Option 2: Static Dashboard with Auto-refresh

# Generate static dashboard every minute
namespace :dashboard do
  desc "Generate static dashboard"
  task :generate do
    # Fetch data
    metrics = fetch_all_metrics
    
    # Generate HTML with embedded data
    template = File.read('templates/dashboard.html.erb')
    html = ERB.new(template).result(binding)
    
    # Write to file
    File.write('public/dashboard/index.html', html)
    
    # Also generate JSON for AJAX updates
    File.write('public/dashboard/data.json', metrics.to_json)
  end
end

# Schedule with cron
# */5 * * * * cd /path && rake dashboard:generate

Option 3: WebSocket Dashboard

gem 'faye-websocket'

require 'faye/websocket'

App = lambda do |env|
  if Faye::WebSocket.websocket?(env)
    ws = Faye::WebSocket.new(env)
    
    ws.on :open do |event|
      # Send initial data
      ws.send(initial_dashboard_data.to_json)
      
      # Start update timer
      timer = EM.add_periodic_timer(30) do
        ws.send(update_dashboard_data.to_json)
      end
      
      ws.on :close do |event|
        EM.cancel_timer(timer)
        ws = nil
      end
    end
    
    ws.rack_response
  else
    # Serve static dashboard
    [200, {'Content-Type' => 'text/html'}, [File.read('public/dashboard.html')]]
  end
end

Automated Scheduled Reports

Generate and distribute reports automatically:

# lib/reporting/daily_report.rb
class DailyReport
  def self.generate
    # Fetch data for yesterday
    start_time = Date.yesterday.beginning_of_day
    end_time = Date.yesterday.end_of_day
    
    data = {
      summary: daily_summary(start_time, end_time),
      top_pages: top_pages(start_time, end_time, limit: 10),
      traffic_sources: traffic_sources(start_time, end_time),
      performance: performance_metrics(start_time, end_time),
      anomalies: detect_anomalies(start_time, end_time)
    }
    
    # Generate report in multiple formats
    generate_html_report(data)
    generate_pdf_report(data)
    generate_email_report(data)
    generate_slack_report(data)
    
    # Archive
    archive_report(data, Date.yesterday)
  end
  
  def self.generate_html_report(data)
    template = File.read('templates/report.html.erb')
    html = ERB.new(template).result_with_hash(data)
    
    File.write("reports/daily/#{Date.yesterday}.html", html)
    
    # Upload to S3 for sharing
    upload_to_s3("reports/daily/#{Date.yesterday}.html")
  end
  
  def self.generate_email_report(data)
    html = render_template('templates/email_report.html.erb', data)
    text = render_template('templates/email_report.txt.erb', data)
    
    Mail.deliver do
      to ENV['REPORT_RECIPIENTS'].split(',')
      subject "Daily Report for #{Date.yesterday}"
      html_part do
        content_type 'text/html; charset=UTF-8'
        body html
      end
      text_part do
        body text
      end
    end
  end
  
  def self.generate_slack_report(data)
    attachments = [
      {
        title: "📊 Daily Report - #{Date.yesterday}",
        fields: [
          {
            title: "Total Visits",
            value: data[:summary][:visits].to_s,
            short: true
          },
          {
            title: "Top Page",
            value: data[:top_pages].first[:path],
            short: true
          }
        ],
        color: "good"
      }
    ]
    
    Slack.notify(
      channel: '#reports',
      attachments: attachments
    )
  end
end

# Schedule with whenever
every :day, at: '6am' do
  runner "DailyReport.generate"
end

Adding Interactive Features

Make dashboards interactive:

1. Date Range Selector

# In your dashboard template
# Backend API endpoint get '/api/metrics' do start_date = params[:start_date] || 7.days.ago.to_s end_date = params[:end_date] || Date.today.to_s metrics = fetch_metrics_for_range(start_date, end_date) content_type :json metrics.to_json end

2. Drill-down Capabilities

# Click on a country to see regional data
<%= pie_chart traffic_by_country, 
  library: {
    onClick: 'function(point) { 
      window.location.href = "/dashboard/country/" + point.name;
    }'
  }
%>

# Country detail page
get '/dashboard/country/:country' do
  @country = params[:country]
  @metrics = fetch_country_metrics(@country)
  
  erb :country_dashboard
end

3. Comparative Analysis

# Compare periods
def compare_periods(current_start, current_end, previous_start, previous_end)
  current = fetch_metrics(current_start, current_end)
  previous = fetch_metrics(previous_start, previous_end)
  
  {
    current: current,
    previous: previous,
    change: calculate_percentage_change(current, previous)
  }
end

# Display comparison

Visits: <%= current[:visits] %> (<%= change[:visits] %>%)

Dashboard Deployment and Optimization

Deploy dashboards efficiently:

1. Caching Strategy

# Cache dashboard data
def cached_dashboard_data
  Rails.cache.fetch('dashboard_data', expires_in: 5.minutes) do
    fetch_dashboard_data
  end
end

# Cache individual charts
def cached_chart(name, &block)
  Rails.cache.fetch("chart_#{name}_#{Date.today}", &block)
end

2. Incremental Data Loading

# Load initial data, then update incrementally

3. Static Export for Sharing

# Export dashboard as static HTML
task :export_dashboard do
  # Fetch all data
  data = fetch_complete_dashboard_data
  
  # Generate standalone HTML with embedded data
  html = generate_standalone_html(data)
  
  # Compress
  compressed = Zlib::Deflate.deflate(html)
  
  # Save
  File.write('dashboard_export.html.gz', compressed)
end

4. Performance Optimization

# Optimize database queries
def optimized_metrics_query
  DB[:metrics].select(
    :timestamp,
    Sequel.lit("SUM(visits) as visits"),
    Sequel.lit("SUM(pageviews) as pageviews")
  ).where(timestamp: start_time..end_time)
   .group(Sequel.lit("DATE_TRUNC('hour', timestamp)"))
   .order(:timestamp)
   .naked
   .all
end

# Use materialized views for complex aggregations
DB.run( SQL)
  CREATE MATERIALIZED VIEW daily_aggregates AS
  SELECT 
    DATE(timestamp) as date,
    SUM(visits) as visits,
    SUM(pageviews) as pageviews,
    COUNT(DISTINCT ip) as unique_visitors
  FROM metrics
  GROUP BY DATE(timestamp)
SQL

Start building your custom dashboard today. Begin with a simple HTML page that displays basic Cloudflare metrics. Then add Ruby scripts to automate data collection. Gradually introduce more sophisticated visualizations and interactive features. Within weeks, you'll have a powerful analytics platform that gives you insights no standard dashboard can provide.