Skip to content

Commit

Permalink
feat: add a openLogs command to help debug issues
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinslin committed Jul 22, 2020
1 parent 4482d13 commit 4f223fc
Show file tree
Hide file tree
Showing 12 changed files with 110 additions and 42 deletions.
15 changes: 12 additions & 3 deletions packages/common-server/src/logger.ts
@@ -1,7 +1,6 @@
// import pino from "pino";

import { env } from "@dendronhq/common-all";
import path from "path";
import pino from "pino";

export class Logger {
Expand All @@ -19,6 +18,9 @@ export class Logger {
// eslint-disable-next-line no-console
console.log(this.name, ctx, msg);
}
debug = (msg: any) => {
this._log(msg);
};
info = (msg: any) => {
this._log(msg);
};
Expand All @@ -27,7 +29,7 @@ export class Logger {
};
}

function createLogger(name?: string) {
function createLogger(name?: string): pino.Logger {
const level = env("LOG_LEVEL", { shouldThrow: false }) || "debug";
const nameClean = name || env("LOG_NAME");

Expand All @@ -41,7 +43,14 @@ function createLogger(name?: string) {
}
}

export { createLogger };
export type DLogger = {
debug: (msg: any) => void;
info: (msg: any) => void;
error: (msg: any) => void;
//fatal: (msg: any) => void;
}

export { createLogger, pino };

export function logAndThrow(logger: Logger, msg: any): never {
logger.error(msg);
Expand Down
12 changes: 8 additions & 4 deletions packages/engine-server/src/drivers/file/parser.ts
Expand Up @@ -13,15 +13,14 @@ import {
createLogger,
globMatch,
mdFile2NodeProps,
pino,
DLogger,
} from "@dendronhq/common-server";
import fs from "fs-extra";
import _ from "lodash";
import path from "path";
import YAML from "yamljs";

// @ts-ignore
const logger = createLogger("FileParser");

export type FileMeta = {
// file name: eg. foo.md, name = foo
prefix: string;
Expand All @@ -46,6 +45,7 @@ function getFileMeta(fpaths: string[]): FileMetaDict {
type FileParserOpts = {
errorOnEmpty?: boolean;
errorOnBadParse?: boolean;
logger?: pino.Logger;
};
type FileParserProps = Required<FileParserOpts>;

Expand All @@ -58,13 +58,17 @@ export class FileParser {

public store: DEngineStore;

public logger: DLogger;

constructor(store: DEngineStore, opts?: FileParserOpts) {
this.errors = [];
this.missing = new Set<string>();
this.opts = _.defaults(opts, {
errorOnEmpty: true,
errorOnBadParse: true,
logger: createLogger("FileParser"),
});
this.logger = this.opts.logger;
this.store = store;
}

Expand All @@ -89,7 +93,7 @@ export class FileParser {
try {
noteProps = mdFile2NodeProps(path.join(store.opts.root, ent.fpath));
} catch (err) {
logger.error({ ctx: "toNode", ent, opts, err });
this.logger.error({ ctx: "toNode", ent, opts, err });
if (opts.errorOnBadParse) {
throw err;
} else {
Expand Down
19 changes: 11 additions & 8 deletions packages/engine-server/src/drivers/file/store.ts
Expand Up @@ -26,16 +26,16 @@ import {
mdFile2NodeProps,
node2MdFile,
schema2YMLFile,
DLogger,
} from "@dendronhq/common-server";

import { FileParser } from "./parser";
import _ from "lodash";
import path from "path";

const logger = createLogger("FileStore");

interface FileStorageOpts {
root: string;
logger?: DLogger;
}

export function fileNameToTitle(name: string): string {
Expand All @@ -54,10 +54,13 @@ export abstract class FileStorageBase {

public rootId: string;

public logger: DLogger;

constructor(opts: FileStorageOpts) {
this.opts = opts;
this.idToPath = {};
this.rootId = "";
this.logger = opts.logger || createLogger("FileStore");
}

abstract doGetFile(id: string): DNodeRawProps<DNodeData>;
Expand All @@ -67,19 +70,19 @@ export abstract class FileStorageBase {
}

async getRoot() {
logger.debug({ ctx: "getRoot", rootId: this.rootId });
this.logger.debug({ ctx: "getRoot", rootId: this.rootId });
return this.doGetFile(this.rootId);
}

async get(id: string, _opts?: QueryOpts): Promise<StoreGetResp> {
let resp: DNodeRawProps<DNodeData>;
logger.debug({ ctx: "get:presGetFile", id });
this.logger.debug({ ctx: "get:presGetFile", id });
if (this.isRoot(id)) {
resp = await this.getRoot();
} else {
resp = this.doGetFile(id);
}
logger.debug({ ctx: "get:postGetFile", resp });
this.logger.debug({ ctx: "get:postGetFile", resp });
return {
data: resp,
};
Expand Down Expand Up @@ -163,7 +166,7 @@ export class FileStorage extends FileStorageBase implements DEngineStore {
const data = new NodeBuilder().buildSchemaFromProps(schemaProps);
// TODO
// this.refreshIdToPath(data)
logger.debug({ ctx: "query:exit:pre" });
this.logger.debug({ ctx: "query:exit:pre" });
return makeResponse<EngineQueryResp>({ data, error: null });
}
throw Error(`unsupported ${queryString}`);
Expand All @@ -175,7 +178,7 @@ export class FileStorage extends FileStorageBase implements DEngineStore {
const data = new NodeBuilder().buildNoteFromProps(noteProps, { schemas });
this.refreshIdToPath(data);

logger.debug({ ctx: "query:exit:pre" });
this.logger.debug({ ctx: "query:exit:pre" });
return makeResponse<EngineQueryResp>({ data, error: null });
}
throw Error(`unsupported ${queryString}`);
Expand All @@ -186,7 +189,7 @@ export class FileStorage extends FileStorageBase implements DEngineStore {
}

refreshIdToPath(nodes: IDNode[]) {
logger.debug({
this.logger.debug({
ctx: "refreshIdToPaths",
nodes: nodes.map((n) => n.toRawProps()),
});
Expand Down
45 changes: 26 additions & 19 deletions packages/engine-server/src/engine.ts
Expand Up @@ -30,15 +30,14 @@ import {
SchemaRawProps,
UpdateNodesOpts,
} from "@dendronhq/common-all";
import { createLogger } from "@dendronhq/common-server";
import { createLogger, DLogger, Logger } from "@dendronhq/common-server";
import fs from "fs-extra";
import Fuse from "fuse.js";
import _ from "lodash";
import FileStorage from "./drivers/file/store";
import { BodyParser } from "./drivers/raw/BodyParser";

let _DENDRON_ENGINE: DendronEngine;
const logger = createLogger("DEngine");

function isAllQuery(qs: string): boolean {
return qs === "**/*";
Expand Down Expand Up @@ -73,6 +72,7 @@ type DendronEngineOpts = {
forceNew?: boolean;
store?: DEngineStore;
mode?: DEngineMode;
logger?: DLogger;
};

type DendronEngineProps = Required<DendronEngineOpts>;
Expand All @@ -94,21 +94,26 @@ export class DendronEngine implements DEngine {

public store: DEngineStore;

public logger: Logger;

static getOrCreateEngine(opts?: DendronEngineOpts): DEngine {
const ctx = "getOrCreateEngine";
if (opts) {
const root = opts.root;
const optsClean: DendronEngineProps = _.defaults(opts || {}, {
forceNew: false,
store: new FileStorage({ root }),
store: new FileStorage({ root, logger: opts?.logger }),
root,
// TODO: remove
cacheDir: "/tmp/dendronCache",
mode: "fuzzy",
logger: createLogger("DEngine"),
});
if (!_DENDRON_ENGINE || optsClean.forceNew) {
if (_.isUndefined(optsClean.root)) {
throw Error(`root must be defined`);
}
optsClean.logger.info({ ctx, msg: "create new engine" });
// TODO
_DENDRON_ENGINE = new DendronEngine(optsClean.store, optsClean);
}
Expand All @@ -132,6 +137,8 @@ export class DendronEngine implements DEngine {
});
this.fullNodes = new Set();
this.queries = new Set();
// @ts-ignore
this.logger = props.logger;

// setup schemas
this.schemas = {};
Expand Down Expand Up @@ -214,7 +221,7 @@ export class DendronEngine implements DEngine {
this.notes[id] = node;
} else {
// exists, merge it
logger.debug({
this.logger.debug({
ctx: "refreshNodes:existingNode",
node: node.toRawProps(),
});
Expand All @@ -231,7 +238,7 @@ export class DendronEngine implements DEngine {
title: n.title,
id: n.id,
}));
logger.debug({
this.logger.debug({
ctx: "refreshNodes",
newNodes,
allNodes,
Expand Down Expand Up @@ -276,7 +283,7 @@ export class DendronEngine implements DEngine {
const tmp = _.find(this.notes, { fname });
if (_.isUndefined(tmp)) {
const msg = `node ${idOrFname} not found`;
logger.error({ ctx, msg });
this.logger.error({ ctx, msg });
throw Error(msg);
}
noteToDelete = tmp;
Expand Down Expand Up @@ -305,7 +312,7 @@ export class DendronEngine implements DEngine {
async get(id: string, mode: QueryMode, opts?: QueryOpts) {
opts = _.defaults(opts || {}, { fullNode: true, createIfNew: true });
let nodeDict;
logger.debug({ ctx: "get", id, opts });
this.logger.debug({ ctx: "get", id, opts });

if (mode === "schema") {
nodeDict = this.schemas;
Expand All @@ -318,14 +325,14 @@ export class DendronEngine implements DEngine {

// a full node has a body and is fully resolved
if (opts?.fullNode && !this.fullNodes.has(id)) {
logger.debug({ ctx: "get:fetchFromStore:pre", id });
this.logger.debug({ ctx: "get:fetchFromStore:pre", id });
const fnResp = await this.store.get(id, {
...opts,
webClient: true,
});
logger.debug({ ctx: "get:fetchFromStore:post", id, opts, fnResp });
this.logger.debug({ ctx: "get:fetchFromStore:post", id, opts, fnResp });
const fullNode = await this.resolveIds(fnResp.data, this.notes);
logger.debug({ ctx: "get:resolve:post", fnResp });
this.logger.debug({ ctx: "get:resolve:post", fnResp });
// TODO:
this.refreshNodes([fullNode], opts);
return { data: fullNode };
Expand All @@ -349,18 +356,18 @@ export class DendronEngine implements DEngine {

// handle all query case
if (isAllQuery(queryString)) {
logger.debug({ ctx: "query:queryAll:pre", mode });
this.logger.debug({ ctx: "query:queryAll:pre", mode });
try {
data = await this.store.query("**/*", mode, {
...opts,
schemas: this.schemas,
});
} catch (err) {
if (err instanceof DendronError) {
logger.info({ ctx, msg: "no root found", mode });
this.logger.info({ ctx, msg: "no root found", mode });
const root = this._createRoot(mode);
await this.store.write(root);
logger.info({ ctx, msg: "post:store.write", mode });
this.logger.info({ ctx, msg: "post:store.write", mode });
return this.query(queryString, mode, opts);
} else {
throw err;
Expand All @@ -383,7 +390,7 @@ export class DendronEngine implements DEngine {
} else {
items = _.map(results, (resp) => resp.item);
}
logger.debug({ ctx: "query:exit:schema", items });
this.logger.debug({ ctx: "query:exit:schema", items });
return makeResponse<EngineQueryResp>({
data: _.map(items, (item) => nodes[item.id]),
error: null,
Expand All @@ -408,7 +415,7 @@ export class DendronEngine implements DEngine {
items[0]?.path !== queryString &&
opts.createIfNew
) {
logger.debug({
this.logger.debug({
ctx: "query:write:pre",
queryString,
item: items[0],
Expand All @@ -432,15 +439,15 @@ export class DendronEngine implements DEngine {
const fetchedFullNodes = await Promise.all(
_.map<IDNode, Promise<IDNode | null>>(items, async (ent) => {
if (!this.fullNodes.has(ent.id)) {
logger.debug({
this.logger.debug({
ctx: "query:fuse.search:post",
status: "fetch full node from store",
});
// FIXME: ratelimit
const fn = await this.get(ent.id, mode);
return fn.data;
}
logger.debug({
this.logger.debug({
ctx: "query:fuse.search:post",
status: "fetch full node from cache",
});
Expand All @@ -451,12 +458,12 @@ export class DendronEngine implements DEngine {
_.filter(fetchedFullNodes, (ent) => !_.isNull(ent)) as IDNode[],
{ fullNode: true }
);
logger.debug({
this.logger.debug({
ctx: "query:fetchedFullNodes:exit",
fetchedFullNodes,
});
}
logger.debug({ ctx: "query:exit:note", items });
this.logger.debug({ ctx: "query:exit:note", items });
return makeResponse<EngineQueryResp>({
data: _.map(items, (item) => this.notes[item.id]),
error: null,
Expand Down
3 changes: 1 addition & 2 deletions packages/plugin-core/.vscode/launch.json
Expand Up @@ -14,12 +14,11 @@
// "--disable-extensions",
"--extensionDevelopmentPath=${workspaceFolder}"
],
"outFiles": ["${workspaceFolder}/out/**/*.js"],
"outFiles": ["${workspaceFolder:plugin-core}/out/**/*.js"],
"env": {
"STAGE": "dev",
"VSCODE_DEBUGGING_EXTENSION": "dendron"
}
//"preLaunchTask": "npm: watch no
},
{
"name": "Extension Tests",
Expand Down
4 changes: 4 additions & 0 deletions packages/plugin-core/package.json
Expand Up @@ -82,6 +82,10 @@
"command": "dendron.dev.resetConfig",
"title": "Dev:Dendron: ResetConfig"
},
{
"command": "dendron.dev.openLogs",
"title": "Dev:Dendron: Open Logs"
},
{
"command": "dendron.openLink",
"title": "Dendron: Open Link"
Expand Down

0 comments on commit 4f223fc

Please sign in to comment.