-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstructured-streaming.py
More file actions
46 lines (34 loc) · 1.77 KB
/
Copy pathstructured-streaming.py
File metadata and controls
46 lines (34 loc) · 1.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# -*- coding: utf-8 -*-
"""
Created on Wed Dec 18 09:15:05 2019
@author: Frank
"""
from pyspark import SparkContext
from pyspark.streaming import StreamingContext
from pyspark.sql import Row, SparkSession
from pyspark.sql.functions import regexp_extract
# Create a SparkSession (the config bit is only for Windows!)
spark = SparkSession.builder.appName("StructuredStreaming").getOrCreate()
# Monitor the logs directory for new log data, and read in the raw lines as accessLines
accessLines = spark.readStream.text("logs")
# Parse out the common log format to a DataFrame
contentSizeExp = r'\s(\d+)$'
statusExp = r'\s(\d{3})\s'
generalExp = r'\"(\S+)\s(\S+)\s*(\S*)\"'
timeExp = r'\[(\d{2}/\w{3}/\d{4}:\d{2}:\d{2}:\d{2} -\d{4})]'
hostExp = r'(^\S+\.[\S+\.]+\S+)\s'
logsDF = accessLines.select(regexp_extract('value', hostExp, 1).alias('host'),
regexp_extract('value', timeExp, 1).alias('timestamp'),
regexp_extract('value', generalExp, 1).alias('method'),
regexp_extract('value', generalExp, 2).alias('endpoint'),
regexp_extract('value', generalExp, 3).alias('protocol'),
regexp_extract('value', statusExp, 1).cast('integer').alias('status'),
regexp_extract('value', contentSizeExp, 1).cast('integer').alias('content_size'))
# Keep a running count of every access by status code
statusCountsDF = logsDF.groupBy(logsDF.status).count()
# Kick off our streaming query, dumping results to the console
query = ( statusCountsDF.writeStream.outputMode("complete").format("console").queryName("counts").start() )
# Run forever until terminated
query.awaitTermination()
# Cleanly shut down the session
spark.stop()