Skip to content

Instantly share code, notes, and snippets.

@kiyoaki
Last active February 25, 2016 04:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kiyoaki/0f6128be8382646e5be3 to your computer and use it in GitHub Desktop.
Save kiyoaki/0f6128be8382646e5be3 to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Owin;
namespace SampleApp.Core.OwinMiddlewares
{
public class UserActionLogMiddleware : OwinMiddleware
{
// このパスにアクセスが来たらログ採取開始
private const string StartAction = "/api/Top/xxxxxxx";
// 無視するパス。システム的なAPIとか
private static readonly List<string> IgnoreActions = new List<string>
{
"/api/Debug/xxxxxxx",
"/api/QuestSelect/xxxxxxx"
};
//ログ採取し続ける期間。過ぎたら離脱とみなす。もっと短くても良いかも
private static readonly TimeSpan LoggingSpan = TimeSpan.FromHours(1);
public UserActionLogMiddleware(OwinMiddleware next) : base(next)
{
}
public override async Task Invoke(IOwinContext context)
{
await Next.Invoke(context);
//ログインユーザーのID
var uid = context.Get<int?>("LoginUid");
if (uid == null)
{
return;
}
if (!context.Request.Path.HasValue || IgnoreActions.Contains(context.Request.Path.Value))
{
return;
}
//RedisクライアントはCloudStructuresをカスタマイズして使ってます
var redis = RedisGroups.Cache.String<ActionLogState>("UserActionLog" + uid.Value);
var now = DateTime.Now;
//行動ログ採取開始
if (context.Request.Path.Value == StartAction)
{
await redis.Set(new ActionLogState
{
Index = 0,
BeforePath = StartAction
}, LoggingSpan);
//レコードをためてStream ImsertするためのUtilityクラス
BigQueryStreaming.Enqueue<Statistics, ActionLog>(new ActionLog
{
Timestamp = now,
Uid = uid.Value,
ToPath = StartAction,
Index = 0
});
return;
}
//Redisの値が取れない場合は行動ログ採取してない
var state = await redis.Get();
if (!state.HasValue)
{
return;
}
//行動ログ採取中
var nextIndex = state.Value.Index + 1;
var beforePath = state.Value.BeforePath;
await redis.Set(new ActionLogState
{
Index = nextIndex,
BeforePath = context.Request.Path.Value
}, LoggingSpan);
BigQueryStreaming.Enqueue<Statistics, ActionLog>(new ActionLog
{
Timestamp = now,
Uid = uid.Value,
FromPath = beforePath,
ToPath = context.Request.Path.Value,
Index = nextIndex
});
}
}
public class ActionLogState
{
public int Index { get; set; }
public string BeforePath { get; set; }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment