Skip to content

Instantly share code, notes, and snippets.

@sidonath
Last active August 29, 2015 14:20
Show Gist options
  • Select an option

  • Save sidonath/b1c7d53b69e7c295fd88 to your computer and use it in GitHub Desktop.

Select an option

Save sidonath/b1c7d53b69e7c295fd88 to your computer and use it in GitHub Desktop.

Revisions

  1. sidonath revised this gist Apr 29, 2015. 1 changed file with 9 additions and 0 deletions.
    9 changes: 9 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,9 @@
    Put JSON files with Slack logs into the `data` directory and save the Ruby script outside that directory.

    Open Terminal and `cd` into the directory with the Ruby script. Now type:

    ```
    ruby parse_logs.rb
    ```

    You should get `output` directory with reports in CSV.
  2. sidonath created this gist Apr 29, 2015.
    78 changes: 78 additions & 0 deletions parse_logs.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,78 @@
    require 'json'
    require 'csv'
    require 'fileutils'

    class SlackParser
    attr_accessor :channels, :users

    OUTPUT_USERS_DIR = 'output/users'
    OUTPUT_TRAFFIC_DIR = 'output/traffic'

    def self.run(*args)
    new(*args).run
    end

    def initialize
    @channels = Dir['data/*'].select { |f| File.directory?(f) }
    @users = JSON.parse(File.read("data/users.json"))
    end

    def run
    channels.each do |channel_path|
    days = Dir["#{channel_path}/*.json"]
    channel = File.basename(channel_path)

    FileUtils.mkdir_p(OUTPUT_USERS_DIR)
    FileUtils.mkdir_p(OUTPUT_TRAFFIC_DIR)

    user_stats = days.reduce({}) { |channel_stats, day|
    messages = JSON.parse(File.read(day))
    real_messages = messages.reject { |m| m.key?('subtype') }

    stats = real_messages.reduce({}) { |daily_stats, message|
    user = message['user']
    daily_stats.merge(user => 1) { |key, old, new| old + new }
    }

    channel_stats.merge(stats) { |key, old, new| old + new }
    }

    user_stats = ids_to_names(user_stats)
    sorted_stats = user_stats.to_a.sort { |a, b| a[1] <=> b[1] }.reverse

    CSV.open("#{OUTPUT_USERS_DIR}/#{channel}.csv", 'wb', headers: %w(username messages), write_headers: true) do |csv|
    sorted_stats.each do |row|
    csv << row
    end
    end

    CSV.open("#{OUTPUT_TRAFFIC_DIR}/#{channel}.csv", 'wb', headers: %w(date messages users_active), write_headers: true) do |csv|
    messages_per_day = days.each do |day|

    messages = JSON.parse(File.read(day))
    real_messages = messages.reject { |m| m.key?('subtype') }

    csv << [
    File.basename(day, '.*'),
    real_messages.count,
    real_messages.map { |m| m['user'] }.uniq.count,
    ]
    end
    end
    end
    end

    private

    def ids_to_names(by_id)
    by_name = {}

    users.each do |user|
    by_name[user['name']] = by_id[user['id']] if by_id.key?(user['id'])
    end

    by_name
    end
    end

    SlackParser.run