Refactor
This commit is contained in:
parent
a617b8dbed
commit
6b0d48423d
|
@ -10,7 +10,7 @@ import { isCollectionOrOrderedCollection, isCollection, IPerson } from '../type'
|
||||||
import { IDriveFile } from '../../../models/drive-file';
|
import { IDriveFile } from '../../../models/drive-file';
|
||||||
import Meta from '../../../models/meta';
|
import Meta from '../../../models/meta';
|
||||||
import htmlToMFM from '../../../mfm/html-to-mfm';
|
import htmlToMFM from '../../../mfm/html-to-mfm';
|
||||||
import { usersChart } from '../../../services/stats';
|
import { usersStats } from '../../../services/stats';
|
||||||
import { URL } from 'url';
|
import { URL } from 'url';
|
||||||
import { resolveNote } from './note';
|
import { resolveNote } from './note';
|
||||||
|
|
||||||
|
@ -180,7 +180,7 @@ export async function createPerson(uri: string, resolver?: Resolver): Promise<IU
|
||||||
}
|
}
|
||||||
}, { upsert: true });
|
}, { upsert: true });
|
||||||
|
|
||||||
usersChart.update(user, true);
|
usersStats.update(user, true);
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
//#region アイコンとヘッダー画像をフェッチ
|
//#region アイコンとヘッダー画像をフェッチ
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import $ from 'cafy';
|
import $ from 'cafy';
|
||||||
import getParams from '../../get-params';
|
import getParams from '../../get-params';
|
||||||
import { driveChart } from '../../../../services/stats';
|
import { driveStats } from '../../../../services/stats';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
desc: {
|
desc: {
|
||||||
|
@ -27,7 +27,7 @@ export default (params: any) => new Promise(async (res, rej) => {
|
||||||
const [ps, psErr] = getParams(meta, params);
|
const [ps, psErr] = getParams(meta, params);
|
||||||
if (psErr) throw psErr;
|
if (psErr) throw psErr;
|
||||||
|
|
||||||
const stats = await driveChart.getStats(ps.span as any, ps.limit);
|
const stats = await driveStats.getChart(ps.span as any, ps.limit);
|
||||||
|
|
||||||
res(stats);
|
res(stats);
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import $ from 'cafy';
|
import $ from 'cafy';
|
||||||
import getParams from '../../get-params';
|
import getParams from '../../get-params';
|
||||||
import { networkChart } from '../../../../services/stats';
|
import { networkStats } from '../../../../services/stats';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
desc: {
|
desc: {
|
||||||
|
@ -27,7 +27,7 @@ export default (params: any) => new Promise(async (res, rej) => {
|
||||||
const [ps, psErr] = getParams(meta, params);
|
const [ps, psErr] = getParams(meta, params);
|
||||||
if (psErr) throw psErr;
|
if (psErr) throw psErr;
|
||||||
|
|
||||||
const stats = await networkChart.getStats(ps.span as any, ps.limit);
|
const stats = await networkStats.getChart(ps.span as any, ps.limit);
|
||||||
|
|
||||||
res(stats);
|
res(stats);
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import $ from 'cafy';
|
import $ from 'cafy';
|
||||||
import getParams from '../../get-params';
|
import getParams from '../../get-params';
|
||||||
import { notesChart } from '../../../../services/stats';
|
import { notesStats } from '../../../../services/stats';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
desc: {
|
desc: {
|
||||||
|
@ -27,7 +27,7 @@ export default (params: any) => new Promise(async (res, rej) => {
|
||||||
const [ps, psErr] = getParams(meta, params);
|
const [ps, psErr] = getParams(meta, params);
|
||||||
if (psErr) throw psErr;
|
if (psErr) throw psErr;
|
||||||
|
|
||||||
const stats = await notesChart.getStats(ps.span as any, ps.limit);
|
const stats = await notesStats.getChart(ps.span as any, ps.limit);
|
||||||
|
|
||||||
res(stats);
|
res(stats);
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import $ from 'cafy';
|
import $ from 'cafy';
|
||||||
import getParams from '../../get-params';
|
import getParams from '../../get-params';
|
||||||
import { usersChart } from '../../../../services/stats';
|
import { usersStats } from '../../../../services/stats';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
desc: {
|
desc: {
|
||||||
|
@ -27,7 +27,7 @@ export default (params: any) => new Promise(async (res, rej) => {
|
||||||
const [ps, psErr] = getParams(meta, params);
|
const [ps, psErr] = getParams(meta, params);
|
||||||
if (psErr) throw psErr;
|
if (psErr) throw psErr;
|
||||||
|
|
||||||
const stats = await usersChart.getStats(ps.span as any, ps.limit);
|
const stats = await usersStats.getChart(ps.span as any, ps.limit);
|
||||||
|
|
||||||
res(stats);
|
res(stats);
|
||||||
});
|
});
|
||||||
|
|
|
@ -7,7 +7,7 @@ import generateUserToken from '../common/generate-native-user-token';
|
||||||
import config from '../../../config';
|
import config from '../../../config';
|
||||||
import Meta from '../../../models/meta';
|
import Meta from '../../../models/meta';
|
||||||
import RegistrationTicket from '../../../models/registration-tickets';
|
import RegistrationTicket from '../../../models/registration-tickets';
|
||||||
import { usersChart } from '../../../services/stats';
|
import { usersStats } from '../../../services/stats';
|
||||||
|
|
||||||
if (config.recaptcha) {
|
if (config.recaptcha) {
|
||||||
recaptcha.init({
|
recaptcha.init({
|
||||||
|
@ -130,7 +130,7 @@ export default async (ctx: Koa.Context) => {
|
||||||
}, { upsert: true });
|
}, { upsert: true });
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
usersChart.update(account, true);
|
usersStats.update(account, true);
|
||||||
|
|
||||||
const res = await pack(account, account, {
|
const res = await pack(account, account, {
|
||||||
detail: true,
|
detail: true,
|
||||||
|
|
|
@ -17,7 +17,7 @@ const requestStats = require('request-stats');
|
||||||
import activityPub from './activitypub';
|
import activityPub from './activitypub';
|
||||||
import webFinger from './webfinger';
|
import webFinger from './webfinger';
|
||||||
import config from '../config';
|
import config from '../config';
|
||||||
import { networkChart } from '../services/stats';
|
import { networkStats } from '../services/stats';
|
||||||
import apiServer from './api';
|
import apiServer from './api';
|
||||||
|
|
||||||
// Init app
|
// Init app
|
||||||
|
@ -104,7 +104,7 @@ export default () => new Promise(resolve => {
|
||||||
const outgoingBytes = queue.reduce((a, b) => a + b.res.bytes, 0);
|
const outgoingBytes = queue.reduce((a, b) => a + b.res.bytes, 0);
|
||||||
queue = [];
|
queue = [];
|
||||||
|
|
||||||
networkChart.update(requests, time, incomingBytes, outgoingBytes);
|
networkStats.update(requests, time, incomingBytes, outgoingBytes);
|
||||||
}, 5000);
|
}, 5000);
|
||||||
//#endregion
|
//#endregion
|
||||||
});
|
});
|
||||||
|
|
|
@ -17,7 +17,7 @@ import { isLocalUser, IUser, IRemoteUser } from '../../models/user';
|
||||||
import delFile from './delete-file';
|
import delFile from './delete-file';
|
||||||
import config from '../../config';
|
import config from '../../config';
|
||||||
import { getDriveFileThumbnailBucket } from '../../models/drive-file-thumbnail';
|
import { getDriveFileThumbnailBucket } from '../../models/drive-file-thumbnail';
|
||||||
import { driveChart } from '../stats';
|
import { driveStats } from '../stats';
|
||||||
|
|
||||||
const log = debug('misskey:drive:add-file');
|
const log = debug('misskey:drive:add-file');
|
||||||
|
|
||||||
|
@ -389,7 +389,7 @@ export default async function(
|
||||||
});
|
});
|
||||||
|
|
||||||
// 統計を更新
|
// 統計を更新
|
||||||
driveChart.update(driveFile, true);
|
driveStats.update(driveFile, true);
|
||||||
|
|
||||||
return driveFile;
|
return driveFile;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ import * as Minio from 'minio';
|
||||||
import DriveFile, { DriveFileChunk, IDriveFile } from '../../models/drive-file';
|
import DriveFile, { DriveFileChunk, IDriveFile } from '../../models/drive-file';
|
||||||
import DriveFileThumbnail, { DriveFileThumbnailChunk } from '../../models/drive-file-thumbnail';
|
import DriveFileThumbnail, { DriveFileThumbnailChunk } from '../../models/drive-file-thumbnail';
|
||||||
import config from '../../config';
|
import config from '../../config';
|
||||||
import { driveChart } from '../stats';
|
import { driveStats } from '../stats';
|
||||||
|
|
||||||
export default async function(file: IDriveFile, isExpired = false) {
|
export default async function(file: IDriveFile, isExpired = false) {
|
||||||
if (file.metadata.storage == 'minio') {
|
if (file.metadata.storage == 'minio') {
|
||||||
|
@ -48,5 +48,5 @@ export default async function(file: IDriveFile, isExpired = false) {
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
// 統計を更新
|
// 統計を更新
|
||||||
driveChart.update(file, false);
|
driveStats.update(file, false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ import registerHashtag from '../register-hashtag';
|
||||||
import isQuote from '../../misc/is-quote';
|
import isQuote from '../../misc/is-quote';
|
||||||
import { TextElementMention } from '../../mfm/parse/elements/mention';
|
import { TextElementMention } from '../../mfm/parse/elements/mention';
|
||||||
import { TextElementHashtag } from '../../mfm/parse/elements/hashtag';
|
import { TextElementHashtag } from '../../mfm/parse/elements/hashtag';
|
||||||
import { notesChart } from '../stats';
|
import { notesStats } from '../stats';
|
||||||
import { erase, unique } from '../../prelude/array';
|
import { erase, unique } from '../../prelude/array';
|
||||||
import insertNoteUnread from './unread';
|
import insertNoteUnread from './unread';
|
||||||
|
|
||||||
|
@ -165,7 +165,7 @@ export default async (user: IUser, data: Option, silent = false) => new Promise<
|
||||||
}
|
}
|
||||||
|
|
||||||
// 統計を更新
|
// 統計を更新
|
||||||
notesChart.update(note, true);
|
notesStats.update(note, true);
|
||||||
|
|
||||||
// ハッシュタグ登録
|
// ハッシュタグ登録
|
||||||
tags.map(tag => registerHashtag(user, tag));
|
tags.map(tag => registerHashtag(user, tag));
|
||||||
|
|
|
@ -6,7 +6,7 @@ import pack from '../../remote/activitypub/renderer';
|
||||||
import { deliver } from '../../queue';
|
import { deliver } from '../../queue';
|
||||||
import Following from '../../models/following';
|
import Following from '../../models/following';
|
||||||
import renderTombstone from '../../remote/activitypub/renderer/tombstone';
|
import renderTombstone from '../../remote/activitypub/renderer/tombstone';
|
||||||
import { notesChart } from '../stats';
|
import { notesStats } from '../stats';
|
||||||
import config from '../../config';
|
import config from '../../config';
|
||||||
import NoteUnread from '../../models/note-unread';
|
import NoteUnread from '../../models/note-unread';
|
||||||
import read from './read';
|
import read from './read';
|
||||||
|
@ -63,5 +63,5 @@ export default async function(user: IUser, note: INote) {
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
// 統計を更新
|
// 統計を更新
|
||||||
notesChart.update(note, false);
|
notesStats.update(note, false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ type ArrayValue<T> = {
|
||||||
type Span = 'day' | 'hour';
|
type Span = 'day' | 'hour';
|
||||||
|
|
||||||
//#region Chart Core
|
//#region Chart Core
|
||||||
type ChartDocument<T extends Obj> = {
|
type Log<T extends Obj> = {
|
||||||
_id: mongo.ObjectID;
|
_id: mongo.ObjectID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -56,12 +56,12 @@ type ChartDocument<T extends Obj> = {
|
||||||
/**
|
/**
|
||||||
* 様々なチャートの管理を司るクラス
|
* 様々なチャートの管理を司るクラス
|
||||||
*/
|
*/
|
||||||
abstract class Chart<T> {
|
abstract class Stats<T> {
|
||||||
protected collection: ICollection<ChartDocument<T>>;
|
protected collection: ICollection<Log<T>>;
|
||||||
protected abstract async generateTemplate(initial: boolean, latestStats?: T): Promise<T>;
|
protected abstract async generateTemplate(init: boolean, latestLog?: T): Promise<T>;
|
||||||
|
|
||||||
constructor(name: string) {
|
constructor(name: string) {
|
||||||
this.collection = db.get<ChartDocument<T>>(`stats.${name}`);
|
this.collection = db.get<Log<T>>(`stats.${name}`);
|
||||||
this.collection.createIndex({ span: -1, date: -1 }, { unique: true });
|
this.collection.createIndex({ span: -1, date: -1 }, { unique: true });
|
||||||
this.collection.createIndex('group');
|
this.collection.createIndex('group');
|
||||||
}
|
}
|
||||||
|
@ -87,7 +87,7 @@ abstract class Chart<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@autobind
|
@autobind
|
||||||
private async getCurrentStats(span: Span, group?: Obj): Promise<ChartDocument<T>> {
|
private async getCurrentLog(span: Span, group?: Obj): Promise<Log<T>> {
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
const y = now.getFullYear();
|
const y = now.getFullYear();
|
||||||
const m = now.getMonth();
|
const m = now.getMonth();
|
||||||
|
@ -100,14 +100,14 @@ abstract class Chart<T> {
|
||||||
null;
|
null;
|
||||||
|
|
||||||
// 現在(今日または今のHour)の統計
|
// 現在(今日または今のHour)の統計
|
||||||
const currentStats = await this.collection.findOne({
|
const currentLog = await this.collection.findOne({
|
||||||
group: group,
|
group: group,
|
||||||
span: span,
|
span: span,
|
||||||
date: current
|
date: current
|
||||||
});
|
});
|
||||||
|
|
||||||
if (currentStats) {
|
if (currentLog) {
|
||||||
return currentStats;
|
return currentLog;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 集計期間が変わってから、初めてのチャート更新なら
|
// 集計期間が変わってから、初めてのチャート更新なら
|
||||||
|
@ -116,7 +116,7 @@ abstract class Chart<T> {
|
||||||
// * 昨日何もチャートを更新するような出来事がなかった場合は、
|
// * 昨日何もチャートを更新するような出来事がなかった場合は、
|
||||||
// * 統計がそもそも作られずドキュメントが存在しないということがあり得るため、
|
// * 統計がそもそも作られずドキュメントが存在しないということがあり得るため、
|
||||||
// * 「昨日の」と決め打ちせずに「もっとも最近の」とします
|
// * 「昨日の」と決め打ちせずに「もっとも最近の」とします
|
||||||
const latestStats = await this.collection.findOne({
|
const latestLog = await this.collection.findOne({
|
||||||
group: group,
|
group: group,
|
||||||
span: span
|
span: span
|
||||||
}, {
|
}, {
|
||||||
|
@ -125,18 +125,18 @@ abstract class Chart<T> {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (latestStats) {
|
if (latestLog) {
|
||||||
// 現在の統計を初期挿入
|
// 現在の統計を初期挿入
|
||||||
const data = await this.generateTemplate(false, latestStats.data);
|
const data = await this.generateTemplate(false, latestLog.data);
|
||||||
|
|
||||||
const stats = await this.collection.insert({
|
const log = await this.collection.insert({
|
||||||
group: group,
|
group: group,
|
||||||
span: span,
|
span: span,
|
||||||
date: current,
|
date: current,
|
||||||
data: data
|
data: data
|
||||||
});
|
});
|
||||||
|
|
||||||
return stats;
|
return log;
|
||||||
} else {
|
} else {
|
||||||
// 統計が存在しなかったら
|
// 統計が存在しなかったら
|
||||||
// * Misskeyインスタンスを建てて初めてのチャート更新時など
|
// * Misskeyインスタンスを建てて初めてのチャート更新時など
|
||||||
|
@ -144,26 +144,26 @@ abstract class Chart<T> {
|
||||||
// 空の統計を作成
|
// 空の統計を作成
|
||||||
const data = await this.generateTemplate(true);
|
const data = await this.generateTemplate(true);
|
||||||
|
|
||||||
const stats = await this.collection.insert({
|
const log = await this.collection.insert({
|
||||||
group: group,
|
group: group,
|
||||||
span: span,
|
span: span,
|
||||||
date: current,
|
date: current,
|
||||||
data: data
|
data: data
|
||||||
});
|
});
|
||||||
|
|
||||||
return stats;
|
return log;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@autobind
|
@autobind
|
||||||
protected commit(query: Obj, group?: Obj, uniqueKey?: string, uniqueValue?: string): void {
|
protected commit(query: Obj, group?: Obj, uniqueKey?: string, uniqueValue?: string): void {
|
||||||
const update = (stats: ChartDocument<T>) => {
|
const update = (log: Log<T>) => {
|
||||||
// ユニークインクリメントの場合、指定のキーに指定の値が既に存在していたら弾く
|
// ユニークインクリメントの場合、指定のキーに指定の値が既に存在していたら弾く
|
||||||
if (
|
if (
|
||||||
uniqueKey &&
|
uniqueKey &&
|
||||||
stats.unique &&
|
log.unique &&
|
||||||
stats.unique[uniqueKey] &&
|
log.unique[uniqueKey] &&
|
||||||
stats.unique[uniqueKey].includes(uniqueValue)
|
log.unique[uniqueKey].includes(uniqueValue)
|
||||||
) return;
|
) return;
|
||||||
|
|
||||||
// ユニークインクリメントの指定のキーに値を追加
|
// ユニークインクリメントの指定のキーに値を追加
|
||||||
|
@ -174,12 +174,12 @@ abstract class Chart<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.collection.update({
|
this.collection.update({
|
||||||
_id: stats._id
|
_id: log._id
|
||||||
}, query);
|
}, query);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.getCurrentStats('day', group).then(stats => update(stats));
|
this.getCurrentLog('day', group).then(log => update(log));
|
||||||
this.getCurrentStats('hour', group).then(stats => update(stats));
|
this.getCurrentLog('hour', group).then(log => update(log));
|
||||||
}
|
}
|
||||||
|
|
||||||
@autobind
|
@autobind
|
||||||
|
@ -197,7 +197,7 @@ abstract class Chart<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@autobind
|
@autobind
|
||||||
public async getStats(span: Span, range: number, group?: Obj): Promise<ArrayValue<T>> {
|
public async getChart(span: Span, range: number, group?: Obj): Promise<ArrayValue<T>> {
|
||||||
const promisedChart: Promise<T>[] = [];
|
const promisedChart: Promise<T>[] = [];
|
||||||
|
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
|
@ -210,7 +210,7 @@ abstract class Chart<T> {
|
||||||
span == 'day' ? new Date(y, m, d - range) :
|
span == 'day' ? new Date(y, m, d - range) :
|
||||||
span == 'hour' ? new Date(y, m, d, h - range) : null;
|
span == 'hour' ? new Date(y, m, d, h - range) : null;
|
||||||
|
|
||||||
const stats = await this.collection.find({
|
const logs = await this.collection.find({
|
||||||
group: group,
|
group: group,
|
||||||
span: span,
|
span: span,
|
||||||
date: {
|
date: {
|
||||||
|
@ -231,12 +231,12 @@ abstract class Chart<T> {
|
||||||
span == 'hour' ? new Date(y, m, d, h - i) :
|
span == 'hour' ? new Date(y, m, d, h - i) :
|
||||||
null;
|
null;
|
||||||
|
|
||||||
const stat = stats.find(s => s.date.getTime() == current.getTime());
|
const log = logs.find(l => l.date.getTime() == current.getTime());
|
||||||
|
|
||||||
if (stat) {
|
if (log) {
|
||||||
promisedChart.unshift(Promise.resolve(stat.data));
|
promisedChart.unshift(Promise.resolve(log.data));
|
||||||
} else { // 隙間埋め
|
} else { // 隙間埋め
|
||||||
const latest = stats.find(s => s.date.getTime() < current.getTime());
|
const latest = logs.find(l => l.date.getTime() < current.getTime());
|
||||||
promisedChart.unshift(this.generateTemplate(false, latest ? latest.data : null));
|
promisedChart.unshift(this.generateTemplate(false, latest ? latest.data : null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -288,7 +288,7 @@ abstract class Chart<T> {
|
||||||
/**
|
/**
|
||||||
* ユーザーに関する統計
|
* ユーザーに関する統計
|
||||||
*/
|
*/
|
||||||
type UsersStats = {
|
type UsersLog = {
|
||||||
local: {
|
local: {
|
||||||
/**
|
/**
|
||||||
* 集計期間時点での、全ユーザー数 (ローカル)
|
* 集計期間時点での、全ユーザー数 (ローカル)
|
||||||
|
@ -324,19 +324,19 @@ type UsersStats = {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
class UsersChart extends Chart<UsersStats> {
|
class UsersStats extends Stats<UsersLog> {
|
||||||
constructor() {
|
constructor() {
|
||||||
super('users');
|
super('users');
|
||||||
}
|
}
|
||||||
|
|
||||||
@autobind
|
@autobind
|
||||||
protected async generateTemplate(initial: boolean, latestStats?: UsersStats): Promise<UsersStats> {
|
protected async generateTemplate(init: boolean, latestLog?: UsersLog): Promise<UsersLog> {
|
||||||
const [localCount, remoteCount] = initial ? await Promise.all([
|
const [localCount, remoteCount] = init ? await Promise.all([
|
||||||
User.count({ host: null }),
|
User.count({ host: null }),
|
||||||
User.count({ host: { $ne: null } })
|
User.count({ host: { $ne: null } })
|
||||||
]) : [
|
]) : [
|
||||||
latestStats ? latestStats.local.total : 0,
|
latestLog ? latestLog.local.total : 0,
|
||||||
latestStats ? latestStats.remote.total : 0
|
latestLog ? latestLog.remote.total : 0
|
||||||
];
|
];
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -370,14 +370,14 @@ class UsersChart extends Chart<UsersStats> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const usersChart = new UsersChart();
|
export const usersStats = new UsersStats();
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
//#region Notes stats
|
//#region Notes stats
|
||||||
/**
|
/**
|
||||||
* 投稿に関する統計
|
* 投稿に関する統計
|
||||||
*/
|
*/
|
||||||
type NotesStats = {
|
type NotesLog = {
|
||||||
local: {
|
local: {
|
||||||
/**
|
/**
|
||||||
* 集計期間時点での、全投稿数 (ローカル)
|
* 集計期間時点での、全投稿数 (ローカル)
|
||||||
|
@ -447,19 +447,19 @@ type NotesStats = {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
class NotesChart extends Chart<NotesStats> {
|
class NotesStats extends Stats<NotesLog> {
|
||||||
constructor() {
|
constructor() {
|
||||||
super('notes');
|
super('notes');
|
||||||
}
|
}
|
||||||
|
|
||||||
@autobind
|
@autobind
|
||||||
protected async generateTemplate(initial: boolean, latestStats?: NotesStats): Promise<NotesStats> {
|
protected async generateTemplate(init: boolean, latestLog?: NotesLog): Promise<NotesLog> {
|
||||||
const [localCount, remoteCount] = initial ? await Promise.all([
|
const [localCount, remoteCount] = init ? await Promise.all([
|
||||||
Note.count({ '_user.host': null }),
|
Note.count({ '_user.host': null }),
|
||||||
Note.count({ '_user.host': { $ne: null } })
|
Note.count({ '_user.host': { $ne: null } })
|
||||||
]) : [
|
]) : [
|
||||||
latestStats ? latestStats.local.total : 0,
|
latestLog ? latestLog.local.total : 0,
|
||||||
latestStats ? latestStats.remote.total : 0
|
latestLog ? latestLog.remote.total : 0
|
||||||
];
|
];
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -514,14 +514,14 @@ class NotesChart extends Chart<NotesStats> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const notesChart = new NotesChart();
|
export const notesStats = new NotesStats();
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
//#region Drive stats
|
//#region Drive stats
|
||||||
/**
|
/**
|
||||||
* ドライブに関する統計
|
* ドライブに関する統計
|
||||||
*/
|
*/
|
||||||
type DriveStats = {
|
type DriveLog = {
|
||||||
local: {
|
local: {
|
||||||
/**
|
/**
|
||||||
* 集計期間時点での、全ドライブファイル数 (ローカル)
|
* 集計期間時点での、全ドライブファイル数 (ローカル)
|
||||||
|
@ -587,13 +587,13 @@ type DriveStats = {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
class DriveChart extends Chart<DriveStats> {
|
class DriveStats extends Stats<DriveLog> {
|
||||||
constructor() {
|
constructor() {
|
||||||
super('drive');
|
super('drive');
|
||||||
}
|
}
|
||||||
|
|
||||||
@autobind
|
@autobind
|
||||||
protected async generateTemplate(initial: boolean, latestStats?: DriveStats): Promise<DriveStats> {
|
protected async generateTemplate(init: boolean, latestLog?: DriveLog): Promise<DriveLog> {
|
||||||
const calcSize = (local: boolean) => DriveFile
|
const calcSize = (local: boolean) => DriveFile
|
||||||
.aggregate([{
|
.aggregate([{
|
||||||
$match: {
|
$match: {
|
||||||
|
@ -612,16 +612,16 @@ class DriveChart extends Chart<DriveStats> {
|
||||||
}])
|
}])
|
||||||
.then(res => res.length > 0 ? res[0].usage : 0);
|
.then(res => res.length > 0 ? res[0].usage : 0);
|
||||||
|
|
||||||
const [localCount, remoteCount, localSize, remoteSize] = initial ? await Promise.all([
|
const [localCount, remoteCount, localSize, remoteSize] = init ? await Promise.all([
|
||||||
DriveFile.count({ 'metadata._user.host': null }),
|
DriveFile.count({ 'metadata._user.host': null }),
|
||||||
DriveFile.count({ 'metadata._user.host': { $ne: null } }),
|
DriveFile.count({ 'metadata._user.host': { $ne: null } }),
|
||||||
calcSize(true),
|
calcSize(true),
|
||||||
calcSize(false)
|
calcSize(false)
|
||||||
]) : [
|
]) : [
|
||||||
latestStats ? latestStats.local.totalCount : 0,
|
latestLog ? latestLog.local.totalCount : 0,
|
||||||
latestStats ? latestStats.remote.totalCount : 0,
|
latestLog ? latestLog.remote.totalCount : 0,
|
||||||
latestStats ? latestStats.local.totalSize : 0,
|
latestLog ? latestLog.local.totalSize : 0,
|
||||||
latestStats ? latestStats.remote.totalSize : 0
|
latestLog ? latestLog.remote.totalSize : 0
|
||||||
];
|
];
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -664,14 +664,14 @@ class DriveChart extends Chart<DriveStats> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const driveChart = new DriveChart();
|
export const driveStats = new DriveStats();
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
//#region Network stats
|
//#region Network stats
|
||||||
/**
|
/**
|
||||||
* ネットワークに関する統計
|
* ネットワークに関する統計
|
||||||
*/
|
*/
|
||||||
type NetworkStats = {
|
type NetworkLog = {
|
||||||
/**
|
/**
|
||||||
* 受信したリクエスト数
|
* 受信したリクエスト数
|
||||||
*/
|
*/
|
||||||
|
@ -699,13 +699,13 @@ type NetworkStats = {
|
||||||
outgoingBytes: number;
|
outgoingBytes: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
class NetworkChart extends Chart<NetworkStats> {
|
class NetworkStats extends Stats<NetworkLog> {
|
||||||
constructor() {
|
constructor() {
|
||||||
super('network');
|
super('network');
|
||||||
}
|
}
|
||||||
|
|
||||||
@autobind
|
@autobind
|
||||||
protected async generateTemplate(initial: boolean, latestStats?: NetworkStats): Promise<NetworkStats> {
|
protected async generateTemplate(init: boolean, latestLog?: NetworkLog): Promise<NetworkLog> {
|
||||||
return {
|
return {
|
||||||
incomingRequests: 0,
|
incomingRequests: 0,
|
||||||
outgoingRequests: 0,
|
outgoingRequests: 0,
|
||||||
|
@ -717,7 +717,7 @@ class NetworkChart extends Chart<NetworkStats> {
|
||||||
|
|
||||||
@autobind
|
@autobind
|
||||||
public async update(incomingRequests: number, time: number, incomingBytes: number, outgoingBytes: number) {
|
public async update(incomingRequests: number, time: number, incomingBytes: number, outgoingBytes: number) {
|
||||||
const inc: Partial<NetworkStats> = {
|
const inc: Partial<NetworkLog> = {
|
||||||
incomingRequests: incomingRequests,
|
incomingRequests: incomingRequests,
|
||||||
totalTime: time,
|
totalTime: time,
|
||||||
incomingBytes: incomingBytes,
|
incomingBytes: incomingBytes,
|
||||||
|
@ -728,5 +728,5 @@ class NetworkChart extends Chart<NetworkStats> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const networkChart = new NetworkChart();
|
export const networkStats = new NetworkStats();
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
Loading…
Reference in New Issue