Tesseract.js seems to print to the console with every call to .recognize(), even with no option parameters attached.
It seems possible to quiet the output with the Tesseract CLI by using the "quiet" flag, but I can't find anything like that for Tesseract.js.
I've scanned through the parameters that could be passed to "options" as found on the Tesseract.js repository:
https://github.com/naptha/tesseract.js/blob/master/docs/tesseract_parameters.md
I've tried setting everything that has to do with "DEBUG" to 0, and I've tried sending the output to a "debug_file" parameter, but nothing I do seems to change the console output.
Here's a basic example with no parameters on the "options" object:
const fs = require('fs');
const Tesseract = require('tesseract.js');
const image = fs.readFileSync('path/to/image.jpg');
const options = {};
Tesseract.recognize(image, options)
.finally((resultOrError) => {
Tesseract.terminate();
}
);
I would expect there to be no output at all here, but instead this gets printed:
pre-main prep time: 76 ms
{ text: '',
html: '<div class=\'ocr_page\' id=\'page_1\' title=\'image ""; bbox 0 0 600 80; ppageno 0\'>\n</div>\n',
confidence: 0,
blocks: [],
psm: 'SINGLE_BLOCK',
oem: 'DEFAULT',
version: '3.04.00',
paragraphs: [],
lines: [],
words: [],
symbols: [] }
UPDATE
Okay, okay. It's early in the morning, I could have tried a little harder here. It looks like Tesseract.js automatically dumps everything to the console if you don't make calls to .catch() and .then(). With the example below, most of the console output disappears.
const fs = require('fs');
const Tesseract = require('tesseract.js');
const image = fs.readFileSync('path/to/image.jpg');
const options = {};
const doSomethingWithResult = (result) => { result };
const doSomethingWithError = (error) => { error };
Tesseract.recognize(image, options)
.then(result => doSomethingWithResult(result))
.catch(err => doSomethingWithError(err))
.finally((resultOrError) => {
Tesseract.terminate();
}
);
Now, only this gets printed to the console:
pre-main prep time: 66 ms
I'd still like a way to suppress this, so I'm going to leave the question unanswered for now. I hope someone can chime in with a suggestion.
Related
I'm trying to deploy my first next.js project on vercel. Locally everything is working.
My problem: When deploying (command: next build) the web app I get the message "Generating static sites (0/2000)" and then nothing happens. The deployment is cancelled after 1h (time expiration).
The problem is somewhere in the (simplified) code below. Here's why: when I deploy the project without the part that follows after const content the deployment is successful - so basically instead of having singleProductResponse AND contentResponse as props, I only have singleProductResponse..
I'm a little stuck and don't know how to solve this. Can someone tell me what I'm doing wrong? Thanks a lot!!
const Item = ({ singleProductResponse, contentResponse }) => {
const router = useRouter();
if (router.isFallback) {
return <div>Loading...</div>;
}
return (
<div className={styles.section}>
<Overview
singleProductResponse={singleProductResponse}
contentResponse={contentResponse}
/>
</div>
);
};
export async function getStaticPaths() {
const itemResponse = await knex("Items");
const paths = itemResponse.map((product) => ({
params: {
brand: product.brand,
item: product.item,
},
}));
return {
paths,
fallback: true,
};
}
export async function getStaticProps({ params }) {
try {
const itemData = await knex("Items").where(
"item",
"like",
`${params.item}`
);
const singleProductResponse = itemData[0];
//!!!!!!!!!when leaving the following part out: deployment is successful!!!!!!!!!!!!
const content = itemData[0].contentList;
const splitContent = content.split(", ");
const contentArray =
typeof splitContent === "string"
? [splitContent]
: splitContent;
const result = await knex("Cos")
.leftJoin("Actives", "Cos.content", "ilike", "Actives.content")
.leftJoin("Alcohol", "Cos.content", "ilike", "Alcohol.content")
.column([
"Cos.content",
"function",
"translationPlant",
"categoryAlcohol",
])
.where((qb) => {
contentArray.forEach((word) => {
qb.orWhere("Cos.content", word);
});
return qb;
});
return {
props: { singleProductResponse, contentResponse },
revalidate: 1,
};
} catch (err) {
console.log(err);
return {
redirect: {
destination: "/",
permanent: false,
},
};
}
}
UPDATE
After digging deeper: I think the problem is that the part after const content is too slow in building process.
When running next build, as well as when deploying on vercel the building process stops after approx. 1h. I suppose this is because of the limit of 45min for building process.
The last message I get is "Generating static pages (1000/2000)" (in vercel and locally) and "Build failed" (vercel). I don't get any other error-messages (also not in the catch block).
I've already tried to optimize the part after const content (each table has an index (clustered indexes -> primary keys), I've redesigned the tables (only 4 tables to join, instead of 6), eliminated everything unnecessary in the query and checked that the database (postgres hosted on heroku - hobby-basic) is also in the US). The performance is better, but still not enough. Does anyone have some suggestions for improvement? TTFB might be a somehow slow.
I need to access the fileHandler object of my logger so I can flush the buffer to the file.
This is my program:
import * as log from "https://deno.land/std#0.75.0/log/mod.ts"
import { Application } from "https://deno.land/x/oak#v6.3.1/mod.ts";
const app = new Application()
const port = 7001
await log.setup({
handlers:{
file: new log.handlers.FileHandler("DEBUG",{
filename: "logger.log",
formatter: lr => {
return `${lr.datetime.toISOString()} [${lr.levelName}] ${lr.msg}`
}
})
},
loggers: {
default: {
level: "DEBUG",
handlers: ["file"]
}
}
})
const logger = log.getLogger()
logger.debug("hi there")
app.use((ctx) => {
ctx.response.body = 'Hi there'
})
console.log(`listening on port ${port}`)
app.listen({ port })
My problem is that the log message is never being written to file.
If I remove the last line ( app.listen() ) it Does write to the file because the process ends.
But if I leave it listening process never ends so the log buffer is never flushed.
If I interrupt the process with Ctrl-C it doesn't write it either
Documentation (https://deno.land/std#0.75.0/log/README.md) says I can force log flush using the flush method from FileHandler. But I don't know how to access the fileHandler object.
So I've tried this:
const logger = log.getLogger()
logger.debug("hi there")
logger.handlers[0].flush()
And it works! but only as javascript, NOT as typescript
As typescript I get this error:
error: TS2339 [ERROR]: Property 'flush' does not exist on type 'BaseHandler'.
logger.handlers[0].flush()
Well, I found a solution.
I just have to import the FileHandler class and cast my handler down from BaseHandler to FileHandler.
So I added this line among the imports:
import { FileHandler } from "https://deno.land/std#0.75.0/log/handlers.ts"
And then after creating the logger:
logger.debug("hi there")
const fileHandler = <FileHandler> logger.handlers[0]
fileHandler.flush()
Looks a little weird, I still guess there must be less quirky / more semantic solution for this. But it works ok.
Let us just recap with the help of Santi's answer.
In my experience logs in file work fine in an ending program. I mean a program which dies by itself or with Deno.exit(0). Problem occurs in a never ending loop. In this case logs don't append in their files. Below is how to overcome this situation :
// dev.js : "I want my logs" example
import {serve} from "https://deno.land/std#0.113.0/http/server_legacy.ts";
import * as log from "https://deno.land/std#0.113.0/log/mod.ts";
// very simple setup, adapted from the official standard lib https://deno.land/std#0.113.0/log
await log.setup({
handlers: {
file: new log.handlers.FileHandler("WARNING", {
filename: "./log.txt",
formatter: "{levelName} {msg}",
}),
},
loggers: {
default: {
level: "DEBUG",
handlers: ["file"],
},
},
});
// here we go
let logger;
logger = log.getLogger();
logger.warning('started');
const fileHandler = logger.handlers[0];
await fileHandler.flush(); // <---- the trick, need to flush ! Thanks Santi
// loop on requests
const srv = serve(`:4321`);
for await (const request of srv) {
request.respond({body: 'bonjour', status: 200});
logger.warning('hit !');
fileHandler.flush(); // <---- flush again
}
Run with
$ deno run -A dev.js
And check the file log.txt with the following trigger
$ curl localhost:4321
This is a very low tech, problably adding important delay to the process. The next level will be to fire a time event to flush every minute or so.
I pretty much copied the example and adjusted the database query. I dont understand why the driver is not recognized?
Version:
Node: v11.13.0
neo4j-driver: "^1.7.5"
I get the Error:
var driver = neo4j.v1.driver(
^
TypeError: Cannot read property 'driver' of undefined
My Code:
var neo4j = require('neo4j-driver').v1;
var driver = neo4j.v1.driver(
'bolt://localhost:7687',
neo4j.auth.basic('neo4j', 'Neo4j')
)
var session = driver.session()
session
.run('MATCH (n:Person) return n', {
//nameParam: 'Alice'
})
.subscribe({
onNext: function(record) {
console.log(record.get('n'))
},
onCompleted: function() {
session.close()
},
onError: function(error) {
console.log(error)
}
})
You probably meant to do this:
var neo4j = require('neo4j-driver').v1;
var driver = neo4j.driver(
...
Or, if for some reason you want to be able to explicitly specify the library version every time you use it, do this:
var neo4j = require('neo4j-driver');
var driver = neo4j.v1.driver(
...
their docs seem screwed up, I had the exact same problem.
remove the v1 and it works. not sure if this defaults to a different version of the driver or something...
let config = require("./config")[env]
const uri = 'bolt://localhost:7687'
const neo4j = require('neo4j-driver');
const driver = neo4j.driver(uri, neo4j.auth.basic(config.username, config.password));
FWIW the way they define a config file is also broken. the node onboarding is pretty much a turn-off.
Sentry by defaults has integration for console.log to make it part of breadcrumbs:
Link: Import name: Sentry.Integrations.Console
How can we make it to work for bunyan logger as well, like:
const koa = require('koa');
const app = new koa();
const bunyan = require('bunyan');
const log = bunyan.createLogger({
name: 'app',
..... other settings go here ....
});
const Sentry = require('#sentry/node');
Sentry.init({
dsn: MY_DSN_HERE,
integrations: integrations => {
// should anything be handled here & how?
return [...integrations];
},
release: 'xxxx-xx-xx'
});
app.on('error', (err) => {
Sentry.captureException(err);
});
// I am trying all to be part of sentry breadcrumbs
// but only console.log('foo'); is working
console.log('foo');
log.info('bar');
log.warn('baz');
log.debug('any');
log.error('many');
throw new Error('help!');
P.S. I have already tried bunyan-sentry-stream but no success with #sentry/node, it just pushes entries instead of treating them as breadcrumbs.
Bunyan supports custom streams, and those streams are just function calls. See https://github.com/trentm/node-bunyan#streams
Below is an example custom stream that simply writes to the console. It would be straight forward to use this example to instead write to the Sentry module, likely calling Sentry.addBreadcrumb({}) or similar function.
Please note though that the variable record in my example below is a JSON string, so you would likely want to parse it to get the log level, message, and other data out of it for submission to Sentry.
{
level: 'debug',
stream:
(function () {
return {
write: function(record) {
console.log('Hello: ' + record);
}
}
})()
}
filters modify the message, and rewrites modify the meta.
Using winston v2^, What are my options if I want to filter out (not to print) certain messages?
I know the question asks for winston 2, but maybe winston 3 is more relevant since this thread is ~8 months old
for winston 2, read https://github.com/winstonjs/winston/blob/2.4.0/docs/transports.md#console-transport and figure it out, probably need to define a formatter as that's a prop in the options for that versions Console transport
figured it out by reading the source code for winston. It seems to depend on this module, logform.
const logform = require('logform');
// const { MESSAGE } = require('triple-beam'); // prop for info in winston formater to expose the shown message
function filterMessagesFormat(filterFunc) {
const formatFunc = (info) => {
if (filterFunc(info.message)) return info;
return null;
};
const format = logform.format(formatFunc);
format.transform = formatFunc;
return format;
}
usage is the same as their formats they define like json, colorize, simple, and others
in the options for winston.createLogger(options), you define a prop called transports and you want one of the values of that array to be the output from this function like:
transports: [
new winston.transports.Console({
format: winston.format.combine(
filterMessagesFormat((msg) => msg !== 'useless message'),
),
handleExceptions: false,
}),
my personal logger creator func https://gist.github.com/jtara1/3128cc6ed3dbea6d507b30967ab0e197 which shows a includes the change to allow a filter func to be used