Writing logs with cloud logging - firebase

I'm having problems with using google-cloud/logging. My objective is to write to a file which is to be created weekly, and i have previously managed to do that. However since yesterday I kept getting this error:
Error: 3 INVALID_ARGUMENT: A monitored resource must be specified for each log entry.
So I updated the google-cloud/logging to the latest version(5.2.2) after reading up about a similar issue of monitored resource not being set automatically. Which did take care of that error, however the logs are not showing up in logs viewer after that change.
My code for the logger utility is as follows
const { Logging } = require('#google-cloud/logging');
exports.LoggingUtil = class LoggingUtil {
constructor(context){
var LogMetadata = {
severity: "INFO",
type: "gce_instance",
labels: {
function_name: process.env.FUNCTION_NAME,
project: process.env.GCLOUD_PROJECT,
region: process.env.FUNCTION_REGION
}
}
this.metadata = {
LogMetadata,
labels: {
execution_id: `${context.eventId}`
}
}
const logging = new Logging();
this.log = logging.log(this.getWeekStamp());
}
getWeekStamp(){
const environmentName = constants.environment.name;
var d = new Date();
var day = d.getDay(),
diff = d.getDate() - day + (day == 0 ? -6:1);
date = new Date(d.setDate(diff)).toLocaleDateString('en-US', { day: '2-digit', month: 'short', year: 'numeric'});
date = date.replace(" ", "-");
return `${date.replace(", ","-")}-week-${environmentName}`;
}
write(text){
var entry = this.log.entry(this.metadata, text);
this.log.write(entry);
}
}
What have I done wrong with this? Any help is appreciated 🙏

I think that you error is related with the way to obtain the metadata variable, because is creating an malformed object that is not readable by the log viewer.
In your method constructor you are creating a metadata object similar to this:
{ "LogMetadata":{
"severity":"INFO",
"type":"gce_instance",
"labels":{
"function_name":process.env.FUNCTION_NAME,
"project":process.env.GCLOUD_PROJECT,
"region":process.env.FUNCTION_REGION
}
},
"labels":{
"execution_id":`${context.eventId}`
}}
that is not a valid MonitoredResource, you can change your code in order to create a valid MonitoredResource for example
var LogMetadata = {
severity: "INFO",
type: "gce_instance",
labels: {
function_name: process.env.FUNCTION_NAME,
project: process.env.GCLOUD_PROJECT,
region: process.env.FUNCTION_REGION
}
}
this.metadata = LogMetadata
this.metadata.labels["execution_id"] = `${context.eventId}`
Example result object
{"severity":"INFO",
"type":"gce_instance",
"labels":{"function_name":process.env.FUNCTION_NAME,
"project":process.env.GCLOUD_PROJECT,
"region": process.env.FUNCTION_REGION,
"execution_id":`${context.eventId}`}
}
Additionally, you can check this example file as a reference to write logs using nodeJS.

Related

Invoking repo actions from multi-select

I've created an UI action using various guides (include Jeff Potts really great ones) successfully and it function exactly as expected - but I want to add that action to the multi-select tool as well. It has been really difficult finding much documentation.
Some things I've tried:
Tried to find out if there was an applicable actionGroup - which there doesn't seem to be.
Tried adding the multi-select tags to my share-config-custom.xml to define the item - it shows up, but I obviously can't seem to use the action ID to reference that action.
My next step was to try and create a js file with a registerAction function in it, which I am able to do and have it run (I can see the console.log dump) but I don't really have any idea how I would go about invoking my repo action from there).
How can I complete this task?
There is already function exist for invoking the repository custom action.This function is defined inside below file.
share-war\components\documentlibrary\actions.js
You can take reference of below code for invoking the repository action.
onActionSimpleRepoAction: function dlA_onActionSimpleRepoAction(record, owner)
{
//ACE-2470 : Clone: Clicking multiple times the simple Workflow approval menu item gives unexpected results.
if (owner.title.indexOf("_deactivated") == -1)
{
// Get action params
var params = this.getAction(record, owner).params,
displayName = record.displayName,
namedParams = ["function", "action", "success", "successMessage", "failure", "failureMessage", "async"],
repoActionParams = {};
for (var name in params)
{
if (params.hasOwnProperty(name) && !Alfresco.util.arrayContains(namedParams, name))
{
repoActionParams[name] = params[name];
}
}
//Deactivate action
var ownerTitle = owner.title;
owner.title = owner.title + "_deactivated";
var async = params.async ? "async=" + params.async : null;
// Prepare genericAction config
var config =
{
success:
{
event:
{
name: "metadataRefresh",
obj: record
}
},
failure:
{
message: this.msg(params.failureMessage, displayName),
fn: function showAction()
{
owner.title = ownerTitle;
},
scope: this
},
webscript:
{
method: Alfresco.util.Ajax.POST,
stem: Alfresco.constants.PROXY_URI + "api/",
name: "actionQueue",
queryString: async
},
config:
{
requestContentType: Alfresco.util.Ajax.JSON,
dataObj:
{
actionedUponNode: record.nodeRef,
actionDefinitionName: params.action,
parameterValues: repoActionParams
}
}
};
// Add configured success callbacks and messages if provided
if (YAHOO.lang.isFunction(this[params.success]))
{
config.success.callback =
{
fn: this[params.success],
obj: record,
scope: this
};
}
if (params.successMessage)
{
config.success.message = this.msg(params.successMessage, displayName);
}
// Acd configured failure callback and message if provided
if (YAHOO.lang.isFunction(this[params.failure]))
{
config.failure.callback =
{
fn: this[params.failure],
obj: record,
scope: this
};
}
if (params.failureMessage)
{
config.failure.message = this.msg(params.failureMessage, displayName);
}
// Execute the repo action
this.modules.actions.genericAction(config);
}
},

Meteor-down load testing

I am trying to make load/stress test to my website. I am using meteor-down. I wrote the test file my_load_test.js
meteorDown.init(function(Meteor) {
var title = "question"
var description = "description"
var tags = ["javascript"]
let data = {
title,
description,
tags
}
Meteor.call('createQuestion', data, function(err, result) {
Meteor.kill();
});
});
meteorDown.run({
concurrency: 10,
url: "http://localhost:3000/discussions",
key: 'mykey',
auth: {
userIds: ['fL6pirusvokposvwX', 'P4DNubMrEQsEQvNX2', 'AN3xqZHaQNmJ4nghe', 'v9XWPKQ7BapnNGY2F']
}
});
But when i run in the terminal, only a time stamp is printed timestamp
or some times an error occurs even though I dont change the test file
error

synced-cron to run once - Meteor

I want to run a 'scheduled job' in meteor which needs to be run only once at a specified time. I have the access of the date object. i've tried the below cron expression but didn't get the expected behavior.
here's the code snippet.
schedule: function(parser) {
var _year = bidStartTime.getFullYear();
var _month = bidStartTime.getMonth();
var _date = bidStartTime.getDate();
var _hours = bidStartTime.getHours();
var _min = bidStartTime.getMinutes();
var bidAsCron = _min+' '+_hours+' '+_date+' '+ _month+' ? '+_year;
console.log('parsed as ' + bidAsCron);
// parser is a later.parse object
// sample parser.cron('25 17 5 10 ? 2015');
// should 5th October 2015 at 5:25 pm
return parser.cron(bidAsCron);
},
Using synced-cron version 1.3.0 you can specify parser.recur().on(date).fullDate(); to schedule a once off (i.e not recurring) event like this:
SyncedCron.add({
name: cron_name,
schedule: function (parser) {
// ending_at is a Date object set to some future date
// there is no recurrence
return parser.recur().on(ending_at).fullDate();
},
job: function () {
// job code
}
});
working example: http://meteorpad.com/pad/mLfyoLnHSECPhQscz/synced-cron%20to%20run%20once

Publishing Users information but without "secret" fields

I am publishing multi-user information (using Meteor.users collection) for the purpose of naming posts creators and have their names and other small details associated with those posts, but I do NOT want to publish the complete documents for each user as they have "secret" login information.
Here is the code I am using:
Meteor.publish("serverforumthread", function(thread){
check(thread, String);
var replies = forumReplies.find({thread: thread});
var users = {};
replies.map(function(r){
users[r.owner] = r.owner;
});
var userids = _.map(users, function(value, key){ return value; });
var projectedFields = {_id:1, username:1, forumStats: 1, services: 0};
var usrs = Meteor.users.find({_id:{$in: userids}}, projectedFields);
var anyUpdateToUsers = false;
usrs.map(function(owner){
var changed = false;
if(!owner.username){
owner.username = owner.emails[0].address.split("#")[0];
changed = true;
}
//owner.forumStats = undefined;
if(!owner.forumStats){
owner.forumStats = {};
owner.forumStats.postCount = 0;
owner.forumStats.postLikes = 0;
owner.forumStats.title = "the newbie";
owner.forumStats.tag = "newbie";
owner.forumStats.img = "http://placehold.it/122x122";
changed = true;
}
if(changed){
anyUpdateToUsers = true;
Meteor.users.update({_id: owner._id}, {$set:{ forumStats:owner.forumStats }});
}
});
if(anyUpdateToUsers) // refresh it
usrs = Meteor.users.find({_id:{$in: userids}}, projectedFields);
usrs.map(function(owner){
console.log(owner);
});
return [replies, usrs];
});
As you can see, I am only interested in publishing relies (posts) for a thread and their associated users username and small forumStats, I want to keep the "services" key secret, as it contains details that should not be published.
A sample output of the "console.log":
{ _id: 'hoRYFbRkXXbHYm8Ty',
createdAt: Tue Jun 03 2014 16:25:42 GMT+0100 (WEST),
emails: [ { address: 'somemail#gmail.com', verified: false } ],
forumStats:
{ postCount: 85,
postLikes: 5,
title: 'the newbie',
tag: 'newbie',
img: 'http://placehold.it/122x122' },
services:
{ password: { srp: [Object] },
resume: { loginTokens: [Object] } } }
What am I doing wrong?
Thank you.
Have a look at the examples in the field specifiers section of the docs, and give this a try:
var projectedFields = {fields: {username:1, forumStats: 1}};
You'll get _id for free, and it will only include the other fields that you specify. Note that you can't mix inclusion and exclusion options, meaning you can't have both 0's and 1's.
If that doesn't work, let me know and I'll look more carefully.

Show file path in the tab when there are several files with the same name

Please take a look at the screenshot:
As you can see there are 3 tabs with 3 different "index.xml" files opened.
I've been looking for an option to show something like "folder/file.extension" in the tabs name to be able to differentiate the files, but I can't find anything.
Using "Go to file" is not very helpful either, because the name of the path for all the files is so long that I can't see the folder containing the files.
Any ideas?
Cheers
UPDATE:
It's possible to increase the 'Go to file' panel width using the mouse and Komodo will remember the size in the future. That helps!
We added the OpenFiles pane specifically for this purpose, please check out View > Tabs & Sidebars > Open Files.
This is what my pane looks like with several files with the same name open:
Additionally you can specify your own patterns, currently this is done programmatically via a macro but in the future you will be able to do this through the UI.
For example, I use the following macro for Komodo development:
ko.openfiles.groupers.byPattern.patterns = [
{
name: 'Plat - %match% - config',
pattern: /\/skin\/plat\/([a-z0-9_-]*)\/_config\//i
},
{
name: 'Plat - %match%',
pattern: /\/skin\/plat\/([a-z0-9_-]*)\//i
},
{
name: 'Module - %match% - skin config',
pattern: /\/(?:module|modules)\/([a-z0-9_-]*)\/skin\/_config\//i
},
{
name: 'Module - %match%',
pattern: /\/(?:module|modules)\/([a-z0-9_-]*)\//i
},
{
name: 'Skin - %match% - config',
pattern: /\/chrome\/skins\/([a-z0-9_-]*)\/_config\//i
},
{
name: 'Skin - %match%',
pattern: /\/chrome\/skins\/([a-z0-9_-]*)\//i
},
{
name: 'Iconset - %match%',
pattern: /\/chrome\/iconsets\/([a-z0-9_-]*)\//i
},
{
name: 'Component - %match%',
pattern: /\/(?:component|components)\/([a-z0-9_-]*)/i
},
{
name: 'Locale',
pattern: /\/locale(?:\/|$)/i
},
{
name: 'Skin',
pattern: /\/skin(?:\/|$)/i
},
{
name: 'Module',
pattern: /\/(?:module|modules)(?:\/|$)/i
},
{
name: 'Component',
pattern: /\/(?:component|components)(?:\/|$)/i
},
];
ko.openfiles.reload(true);
You can read up on macro's here: http://docs.activestate.com/komodo/8.5/macros.html#macros_writing
Using the above macro I need to make sure I have the "Group By Pattern" option selected, then I just run the macro and the same files you see in my above screenshot will be grouped according to the patterns I specified:
Note that this requires the latest version of Komodo (8.5).
Also note that if you use the Open Files pane you may find that you do not need the regular tabs anymore, you can disable these under "View > View Editor Tabs".
Hope that helps, good luck!
Use the Komodo JavaScript API to change the default display of tab titles:
komodo.assertMacroVersion(3);
function changeTabTitles(useLongerTitle, splitLength) {
try {
var vm = ko.views.manager.topView;
var box = document.getAnonymousNodes(vm)[0];
// Get the views-tabbed elements.
var topTabs = box.firstChild;
var bottomTabs = box.lastChild;
if (!useLongerTitle) {
// Restore the original functionality.
if (topTabs._tweakui_updateLeafName) {
topTabs.updateLeafName = topTabs._tweakui_updateLeafName;
topTabs._tweakui_updateLeafName = null;
}
if (bottomTabs._tweakui_updateLeafName) {
bottomTabs.updateLeafName = bottomTabs._tweakui_updateLeafName;
bottomTabs._tweakui_updateLeafName = null;
}
} else {
// Save the original functionality.
if (!topTabs._tweakui_updateLeafName)
topTabs._tweakui_updateLeafName = topTabs.updateLeafName;
if (!bottomTabs._tweakui_updateLeafName)
bottomTabs._tweakui_updateLeafName = bottomTabs.updateLeafName;
// Replace the updateLeafName implementation to use something
// different for the tab label.
var osSvc = Components.classes["#activestate.com/koOs;1"].
getService(Components.interfaces.koIOs);
var dirsep = osSvc.sep;
topTabs.updateLeafName =
bottomTabs.updateLeafName = function(view) {
view.parentNode._tab.label = view.title;
if (view.document) {
view.parentNode._tab.setAttribute('crop', 'start');
var path = view.document.displayPath;
var sep = dirsep;
if (path.lastIndexOf(sep) == -1) {
// Try using the URI separator.
sep = "/";
}
var path_split = path.split(sep);
var l = path_split.length;
var label = path_split.slice(l-splitLength, l).join(sep);
view.parentNode._tab.label = label;
view.parentNode._tab.setAttribute('tooltiptext',view.document.displayPath);
this.tabbox.firstChild.scrollBoxObject.ensureElementIsVisible(this.tabbox.firstChild.selectedItem);
}
}
}
Save it as a macro and customize it to your liking.
code updated for Komodo 8.5 (view.document -> view.koDoc)
komodo.assertMacroVersion(3);
try {
var vm = ko.views.manager.topView;
var box = document.getAnonymousNodes(vm)[0];
// get the views-tabbed elements
var tabset1 = box.firstChild;
var tabset2 = box.lastChild;
// replace the updateLeafName implementation to use something different
// for the tab label
tabset1.updateLeafName =
tabset2.updateLeafName = function(view) {
view.parentNode._tab.label = view.title;
if (view.koDoc) {
var language = view.koDoc.language;
if (language == 'Python') {
var parts = view.koDoc.displayPath.split('/');
var len = parts.length;
var label = '';
if (len > 2) {
label += parts[len-2] + '/';
}
label += parts[len-1];
view.parentNode._tab.setAttribute('crop', 'start');
view.parentNode._tab.label = label;
view.parentNode._tab.setAttribute('tooltiptext',view.koDoc.displayPath);
this.tabbox.firstChild.scrollBoxObject.ensureElementIsVisible(this.tabbox.firstChild.selectedItem);
}
}
};
// the "on startup" trigger happens after files
// are opened, so we need to call updateLeafName
// for each opened view. Files opened after startup
// will be fine
var views = ko.views.manager.topView.getViews(true);
for (var i=0; i < views.length; i++) {
if (views[i].koDoc) {
views[i].updateLeafName(views[i]);
}
}
} catch(e) {
alert(e);
}

Resources