How to log stackdriver entries using stackdriver logging nodejs lib #google-cloud/logging - node.js

I am using protractor having Jasmine where I intergrated stackdriver lib #google-cloud/logging. When I run this lib, I get entryId however I dont see logs in stackdriver. I debug the issues and seems like some issues with async-await concepts:
jasmine.getEnv().addReporter({
specDone: function (result) {
if(result.failedExpectations.length){
count++;
}
},
suiteDone: function (result) {
console.log(count);
if (count!=0) {
(async() => {
console.log('1')
await stackdriverLogEntry("Your GCP project", "protractor-log-data", "success: false");
console.log('2')
})()
} else {
(async() => {
console.log('3')
await stackdriverLogEntry("Your GCP project", "protractor-log-data", "success: true");
console.log('4')
})()
};
}
})
---------------------------------------------------------------------------
this.stackdriverLogEntry = async function (projectId, logName, text) {
// Creates a client
const logging = new Logging({ projectId: projectId });
// Selects the log to write to
const log = logging.log(logName);
// The metadata associated with the entry
const metadata = {
resource: { type: 'global' },
};
// Prepares a log entry
const entry = log.entry(metadata, text);
console.log(JSON.stringify(entry));
// Writes the log entry
await log.write(entry);
console.log(`metadata: ${JSON.stringify(metadata)}`);
console.log(`Logged: ${text}`);
};
Any HELP here would be appreciated!!!

Related

Error: No Contract deployed with name Ebay

Getting this error while testing my Ebay Contract
ITs An Ebay Smart Contract Where Products are being Auctioned
yarn run v1.22.15
warning package.json: No license field
$ "E:\Block Chain Projects\30_SMARTCONTRACTS.sol\A Way To Testing\node_modules\.bin\hardhat" test
Ebay Smart Contract
Upload Product function
This is deployer0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266
1) "before each" hook for "if the base Price is less than 0 or invalid should revert"
0 passing (2s)
1 failing
1) Ebay Smart Contract
"before each" hook for "if the base Price is less than 0 or invalid should revert":
Error: No Contract deployed with name Ebay
at Object.getContract (node_modules\#nomiclabs\hardhat-ethers\src\internal\helpers.ts:447:11)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at Context.<anonymous> (test\Test.js:18:12)
error Command failed with exit code 1.
MY TEST.js
//it
//describe
//beforeEach
const { expect, assert } = require("chai");
const { ethers, getNamedAccounts } = require("hardhat");
describe("Ebay Smart Contract", async function() {
let Ebay;
let deployer;
const product = {
name: "CYCLE",
description: "gare cycles",
BasePrice: "5",
};
beforeEach(async () => {
deployer = (await getNamedAccounts()).deployer;
console.log("This is deployer" + deployer);
Ebay = await ethers.getContract("Ebay", deployer);
});
describe("Upload Product function", async function() {
it("if the base Price is less than 0 or invalid should revert", async function() {
expect(
Ebay.UploadProduct(product.name, product.description, product.BasePrice)
).to.be.revertedWith(Base_Price_cannot_be_Zero());
});
});
});
My deploy.js
const { ethers, deployments } = require("hardhat");
require("dotenv").config();
async function main() {
// const { deploy, log } = deployments;
//const { deployer } = await getNamedAccounts();
const Auction = await ethers.getContractFactory("Ebay");
const auction = await Auction.deploy();
await auction.deployed();
console.log(auction.address);
// const Auction = await deploy("Auctionbargain", {
// from: deployer,
// args: [],
// log: true,
// waitconfirmations: network.config.blockConfirmations || 1,
// });
//console.log(Auction.address);
//log("------------------------------------");
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.log(error);
process.exit(1);
});
hardhatconfig.js
require("#nomicfoundation/hardhat-toolbox");
require("hardhat-deploy");
require("dotenv").config();
/** #type import('hardhat/config').HardhatUserConfig */
module.exports = {
solidity: {
compilers: [{ version: "0.6.6" }, { version: "0.8.8" }],
},
networks: {
hardhat: {
chainId: 31337,
},
// goerli: {
// url: GOERLI_RPC_URL,
// accounts: [PRIVATE_KEY],
// chainId: 5,
// blockConfirmations: 6,
// },
},
namedAccounts: {
deployer: {
default: 0, // here this will by default take the first account as deployer
},
},
};
It was correctly deployed but gave error everytime i try to test it
I Tried using ABI in place of deployer in my test.js but it did give me the same error
Are you sure you deployed the contract on the same network on which you’re testing? it says:
Error: No Contract deployed with name Ebay
this can happen if you‘re testing on another network where the contract isn’t deployed at.
Also consider that the contract is really named Ebay. I can’t check that since you didn’t provide the solidity file.

Jasmine reporter publishing data to prometheus overwrites previous job & metrics

I am trying to write a reporter in jasmine that pushes data to prometheus. I am able to execute the tests and report them in one go but as soon as I re-execute these tests the existing job with the published metrics just gets overwritten with new data. What I want is to attach metrics to an existing job without removing the data that already exists.
This will allow me to run the specs in parallel as well, which can be done but the prometheus data just keeps being overwritten.
masterReporter.js
const PrometheusUtil = require("../utils/prometheusUtil");
class masterReporter {
async suiteDone(result) {
const prometheusUtil = new PrometheusUtil("http://localhost:9091", process.env.BASEURL);
await prometheusUtil.setTestExecutionMetrics(
{"region": prometheusUtil.region,
"spec_name": result.fullName, "tenant": process.env.BASEURL});
}
}
module.exports = masterReporter;
prometheusUtil.js
const client = require("prom-client");
class PrometheusUtil {
constructor(baseUrl, environment) {
this.environment = environment;
this.baseUrl = baseUrl;
this.name = environment.replace("https://", "").replace(".com", "")
.replaceAll(".", "_").replaceAll("-", "_").replaceAll("/", "");
this.testExecution = new client.Gauge({
name: this.name,
help: "Gauge for test execution results storing region info.",
labelNames: ["region", "tenant", "spec_name", "failure_classification_value"],
});
this.gateway = new client.Pushgateway(baseUrl);
this.setRegion(environment);
}
async setTestExecutionMetrics(value, number) {
try {
this.setRegion(this.environment);
this.testExecution.set(value, number);
this.gateway.pushAdd({jobName: this.name}, function(err, resp, body) {
if (err) {
console.log(err);
}
if (body) {
console.log(body);
}
});
} catch (error) {
console.log(error);
}
}
setRegion(baseUrl) {
if (baseUrl.includes(".us.")) {
this.region = "US";
}
else {
console.log(`Sorry, region could not be defined for ${baseUrl}.`);
}
return this.region;
}
}
module.exports = PrometheusUtil;

Why am I only getting Mailgun.js error in Cloud Run?

I'm trying to send an email using Mailgun's npm client - Mailgun.js.
When sending in development mode, everything works correctly. But when I upload the Node server to Cloud Run, something breaks.
Here is the code in the sendEmail helper file:
import formData from 'form-data';
import Mailgun from 'mailgun.js';
const sendEmail = async ({ to, subject, text, attachment, scheduledDate }) => {
const mailgun = new Mailgun(formData);
const mg = mailgun.client({
username: 'api',
key: process.env.MAILGUN_KEY,
url: 'https://api.eu.mailgun.net'
});
const data = {
from: `<myemail#mydomain.com>`,
to,
subject,
text
};
if (attachment) {
data.attachment = attachment;
}
if (scheduledDate) {
data['o:deliverytime'] = new Date(scheduledDate).toUTCString();
}
try {
const result = await mg.messages.create(process.env.MAILGUN_DOMAIN, data);
if (result.status && result.status !== 200) {
throw ({ code: result.status, message: result.message });
}
return true;
} catch(err) {
console.log(err);
return { error: err };
}
};
export default sendEmail;
And then in another file:
import { Router } from 'express';
import generateInvoicePDF from '../helpers/generateInvoicePDF.js';
import sendEmail from '../helpers/sendEmail.js';
const router = Router();
router.post('/email', async (req, res, next) => {
try {
const file = await generateInvoicePDF(invoice);
if (file?.error) {
throw ({ code: pdf.error.code, message: pdf.error.message });
}
const email = await sendEmail({
to: 'testemail#example.com',
subject: 'Invoice',
text: 'Test',
attachment: { filename: 'Invoice', data: file }
});
if (email?.error) {
throw ({ code: email.error.code, message: email.error.message });
}
res.status(200).json({ success: true });
} catch(err) {
next(err);
}
});
export default router;
The error I get when in production mode in Cloud Run's logs is:
TypeError: fetch failed
at Object.processResponse (node:internal/deps/undici/undici:5575:34)
at node:internal/deps/undici/undici:5901:42
at node:internal/process/task_queues:140:7
at AsyncResource.runInAsyncScope (node:async_hooks:202:9)
at AsyncResource.runMicrotask (node:internal/process/task_queues:137:8) {
cause: TypeError: object2 is not iterable
at action (node:internal/deps/undici/undici:1661:39)
at action.next (<anonymous>)
at Object.pull (node:internal/deps/undici/undici:1709:52)
at ensureIsPromise (node:internal/webstreams/util:172:19)
at readableStreamDefaultControllerCallPullIfNeeded (node:internal/webstreams/readablestream:1884:5)
at node:internal/webstreams/readablestream:1974:7
}
Why the hell does it work in development mode on my local machine, but not when uploaded to Cloud Run?
For anyone struggling with something similar - I eventually figured out the problem.
On my local machine, where everything was working as expected, I'm using Node v16.15.0, whereas in the Dockerfile, I had specified
FROM node:latest
and therefore Cloud Run was using a newer version, which led to the problems...
I've now deployed using version 16.15.0 and everything works fine

How to make kuzzle-device-manager plugin API actions works?

I successfully installed and loaded kuzzle-device-manager in the backend file:
import { Backend } from 'kuzzle';
import { DeviceManagerPlugin } from 'kuzzle-device-manager';
const app = new Backend('playground');
console.log(app.config);
const deviceManager = new DeviceManagerPlugin();
const mappings = {
updatedAt: { type: 'date' },
payloadUuid: { type: 'keyword' },
value: { type: 'float' }
}
deviceManager.devices.registerMeasure('humidity', mappings)
app.plugin.use(deviceManager)
app.start()
.then(async () => {
// Interact with Kuzzle API to create a new index if it does not already exist
console.log(' started!');
})
.catch(console.error);
But when i try to use controllers from that plugin for example device-manager/device with create action i get an error output.
Here is my "client" code in js:
const { Kuzzle, WebSocket } = require("kuzzle-sdk")
const kuzzle = new Kuzzle(
new WebSocket('KUZZLE_IP')
)
kuzzle.on('networkError', error => {
console.error('Network Error: ', error);
})
const run = async () => {
try {
// Connects to the Kuzzle server
await kuzzle.connect();
// Creates an index
const result = await kuzzle.query({
index: "nyc-open-data",
controller: "device-manager/device",
action: "create",
body: {
model: "model-1234",
reference: "reference-1234"
}
}, {
queuable: false
})
console.log(result)
} catch (error) {
console.error(error.message);
} finally {
kuzzle.disconnect();
}
};
run();
And the result log:
API action "device-manager/device":"create" not found
Note: The nyc-open-data index exists and is empty.
We apologize for this mistake in the documentation, the device-manager/device:create method is not available because the plugin is using auto-provisioning until the v2.
You should send a payload to your decoder, the plugin will automatically provision the device if it does not exists https://docs.kuzzle.io/official-plugins/device-manager/1/guides/decoders/#receive-payloads

Dynamically mock dependencies with Jest

I have a method that logs a message via one function in a node environment and via a different function in a browser environment. To check whether I am in a node or browser environment I use the libraries detect-node and is-browser like so:
const isNode = require('detect-node');
const isBrowser = require('is-browser');
log(level, message, data) {
if (isNode) {
this.nodeTransport.log(level, this.name, message, data);
}
if (isBrowser) {
this.browserTransport.log(level, this.name, message, data);
}
}
The variables isNode and isBrowser are set to true and false (automatically via the package) depending on, well, if I'm in a browser or in a node env.
Now I want to test this behavior using jest so I need to mock these npm packages. This is what I tried:
function setup() {
const loggerName = 'Test Logger';
const logger = new Logger(loggerName);
logger.nodeTransport = { log: jest.fn() };
logger.browserTransport = { log: jest.fn() };
logger.splunkTransport = { log: jest.fn() };
return { logger, loggerName };
}
test('it should call the the appropriate transports in a node environment', () => {
const { logger } = setup();
const message = 'message';
jest.mock('detect-node', () => true);
jest.mock('is-browser', () => false);
logger.log('error', message, []);
expect(logger.nodeTransport.log).toHaveBeenCalled();
expect(logger.browserTransport.log).not.toHaveBeenCalled();
});
test('it should call the the appropriate transports in a browser environment', () => {
const { logger } = setup();
const message = 'message';
jest.mock('detect-node', () => false);
jest.mock('is-browser', () => true);
logger.log('error', message, []);
expect(logger.nodeTransport.log).not.toHaveBeenCalled();
expect(logger.browserTransport.log).toHaveBeenCalled();
});
You see, I am using jest.mock to mock detect-node and is-browser and give it different return values. However, this just does not work. The first test is green because (I assume) Jest runs in node, but the second test fails saying
Expected mock function not to be called but it was called with:
["error", "Test Logger", "message", []]
Use .mockClear() to reset the mock calls between tests.
afterEach(() => {
logger.nodeTransport.log.mockClear();
logger.browserTransport.log.mockClear();
});

Resources