Google Cloud trace Custom trace only works a few times - node.js

I have activated Google Cloud Tracer with nodejs & express, works well in automatic mode, registers calls to the api correctly.
I try to create a trace manually, to know the execution time of intermediate steps.
controller (req, res) {
tracer.runInRootSpan({ name: 'dnd-task' }, (rootSpan) => {
//promise
myPromise(rootSpan)
.then((data) => {
rootSpan.endSpan()
res.ok(data)
})
.catch((err)=>{
rootSpan.endSpan()
res.send(err)
})
})
}
but Google Cloud Trace only lists 1 or 2 calls, while automatically generated calls show thousands of API calls.
I also read the documentation to try to get the context of express.js middleware, but I didn't find a way to get the context.
from: google-cloud-trace
a root span is automatically started whenever an incoming request is received (in other words, all middleware already runs within a root span).
Update base on #kjin comment:
inside a controller in express you only need
tracer.createChildSpan({name: 'name'})

If you have automatic tracing enabled and also generate root spans within a request listener using the custom span API, then the root span will be ignored because it was created within a pre-existing root span (the one that was automatically started for this request). This is my guess based on the code presented here, but you should be able to accomplish what you want by instead creating a child span. (Custom root spans are meant for work that occur outside of a request's lifecycle -- such as periodic work.)
Re: Express.js middleware context -- I am not exactly sure what you mean here, but the Trace Agent doesn't store any of the request listener arguments in the trace context.
As an additional note -- you'll get a quicker response time if you report an issue directly to the GitHub repository to which you linked.
Hope this helps!

Related

Using gcloud commands in nodejs application

Some gcloud commands don't have API or client library support (for example - this one).
In these cases, is there a simple way to run gcloud commands from a nodejs application?
The gcloud endpoints service commands for IAM policy are difficult for me to check quickly but, if IIRC (and if this is similar to gcloud projects commands for IAM policy), it's not that there's no API, but that there's no single API call.
What you can always do with gcloud is append --log-http to see what happens beneath the covers. With IAM policy mutations (off-top-of-head), you get the policy, mutate it, and then apply the changes back using the etag the GET gave you. The backend checks the policy's state (the etag is like a hash of the policy) and, if it's unchanged, you can make the change.
If this is what's happening here, you should be able to repro the functionality in NodeJS using the existing (!) APIs and, if you're using API Client Libraries (rather than Cloud Client libraries), the functionality will be available.
Apart from the complexity involved in shelling out to gcloud, you'll need to also authenticate it and then you'll need to (un)marshal data to the shell and manage errors. Ergo, it's messy and generally discouraged.
In node.js ,we have child_process module. As the name suggests the child_process provides function like spawn or exec that creates new child process that executes shell command like independent process. spawn is a function that takes the main command as
first argument and other command line options as an array values in place of second parameter.
So with respect to link that you share, you might end-up writing something like this :
const { spawn } = require("child_process");
const listening = spawn('gcloud', ['endpoints', 'services', 'blah', '--option','someValue']);
listening.stdout.on("data", data => {
console.log(`stdout: ${data}`);
});
listening.stderr.on("data", data => {
console.log(`stderr: ${data}`);
});
listening.on('error', (error) => {
console.log(`error: ${error.message}`);
});
References :
https://nodejs.org/api/child_process.html#child_process_child_process_spawn_command_args_options
I'm not sure this directly answers your question but there is an npm package that can help you run unix commands from within the app.
Check out shell.js

Feathers JS nested Routing or creating alternate services

The project I'm working on uses the feathers JS framework server side. Many of the services have hooks (or middleware) that make other calls and attach data before sending back to the client. If I have a new feature that needs to query a database but for a only few specific things I'm thinking I don't want to use the already built out "find" method for this database query as that "find" method has many other unneeded hooks and calls to other databases to get data I do not need for this new query on my feature.
My two solutions so far:
I could use the standard "find" query and just write if statements in all hooks that check for a specific string parameter that can be passed in on client side so these hooks are deactivated on this specific call but that seems tedious especially if I find this need for several other different services that have already been built out.
I initialize a second service below my main service so if my main service is:
app.use('/comments', new JHService(options));
right underneath I write:
app.use('/comments/allParticipants', new JHService(options));
And then attach a whole new set of hooks for that service. Basically it's a whole new service with the only relation to the origin in that the first part of it's name is 'comments' Since I'm new to feathers I'm not sure if that is a performant or optimal solution.
Is there a better solution then those options? or is option 1 or option 2 the most correct way to solve my current issue?
You can always wrap the population hooks into a conditional hook:
const hooks = require('feathers-hooks-common');
app.service('myservice').after({
create: hooks.iff(hook => hook.params.populate !== false, populateEntries)
});
Now population will only run if params.populate is not false.

Uploading photos using Grails Services

I would like to ask, What would be the most suitable scope for my upload photo service in Grails ? I created this PhotoService in my Grails 2.3.4 web app, all it does is to get the request.getFile("myfile") and perform the necessary steps to save it on the hard drive whenever a user wants to upload an image. To illustrate what it looks like, I give a skeleton of these classes.
PhotoPageController {
def photoService
def upload(){
...
photoService.upload(request.getFile("myfile"))
...
}
}
PhotoService{
static scope="request"
def upload(def myFile){
...
// I do a bunch of task to save the photo
...
}
}
The code above isn't the exact code, I just wanted to show the flow. But my question is:
Question:
I couldn't find the exact definition of these different grails scopes, they have a one liner explanation but I couldn't figure out if request scope means for every request to the controller one bean is injected, or each time a request comes to upload action of the controller ?
Thoughts:
Basically since many users might upload at the same time, It's not a good idea to use singleton scope, so my options would be prototype or request I guess. So which one of them works well and also which one only gets created when the PhotoService is accessed only ?
I'm trying to minimize the number of services being injected into the application context and stays as long as the web app is alive, basically I want the service instance to die or get garbage collect at some point during the web app life time rather than hanging around in the memory while there is no use for it. I was thinking about making it session scope so when the user's session is terminated the service is cleaned up too, but in some cases a user might not want to upload any photo and the service gets created for no reason.
P.S: If I move the "def photoService" within the upload(), does that make it only get injected when the request to upload is invoked ? I assume that might throw exception because there would be a delay until Spring injects the service and then the ref to def photoService would be n
I figured out that Singleton scope would be fine since I'm not maintaining the state for each request/user. Only if the service is supposed to maintain state, then we can go ahead and use prototype or other suitable scopes. Using prototype is safer if you think the singleton might cause unexpected behavior but that is left to testing.

ServiceStack message queue handling and Profiler

I'm currently trying out the persistent mini profiler feature of ServiceStack and I'm currently having trouble registering profile information for my Redis Message Queue handlers.
A bit more background:
I have some regular REST api handlers which takes in a request, defers some updates of account information and replies OK back to the caller. These messages are posted to a Redis server, using the ServiceStack Redis MQ pattern. Therefore, the Redis message handling is registered as:
var redisFactory = new PooledRedisClientManager(redisClients);
var mqHost = new RedisMqServer(redisFactory, retryCount: 2);
var defaultThreadCount = 4;
mqHost.RegisterHandler<SomeDto>(m => this.ServiceController.ExecuteMessage(m), noOfThreads:defaultThreadCount);
mqHost.RegisterHandler<SomeOtherDto>(m => this.ServiceController.ExecuteMessage(m), noOfThreads:defaultThreadCount);
mqHost.Start();
And my messages are being handled properly too.
In a custom ServiceRunner I've enabled profiling of all requests in the BeforeEachRequest and added a custom Profiler step like this:
public override void BeforeEachRequest(IRequest requestContext, T request)
{
Profiler.Start();
using (Profiler.StepStatic("Executing handler"))
{
base.BeforeEachRequest(requestContext, request);
}
}
All my HTTP REST requests are making it to the SQL tables, but none of the MQ handler calls are registered. And I'm 100% confident that the handlers are indeed being executed, since the result of that execution is stored in a MongoDB collection.
Anything I'm missing?
-- EDIT --
I forgot to mention that this project is indeed hosted via an ASP.NET application. The AppHost is initialized in Global.asax App_Start - I just found it more convenient to have "before request" handing in a custom service runner rather than the ASP.NET Begin_Request handler.
I have a similar problem with a self hosted server. The problem is that the profiler uses HttpContext.Current to store the profiling results. If there is no valid context it does not know which profiling 'session' to add the results to.
It is possible to implement your own ProfilingProvider by setting Profile.Settings.ProfilingProvider, but, unless I am missing something, it will be tricky (if not impossible) to implement this properly in an Async environment with the current IProfilerProvider interface.
I wrote a very simple and naive provider which you can use for profiling. This will not pick up any of the steps that ServiceStack already adds by default, but it might still be useful for your own debugging.
Example use:
Profiler.Settings.ProfilerProvider = RequestProfilerProvider.Instance;
PreRequestFilters.Add((req, res) => RequestProfiler.Start(req));
GlobalRequestFilters.Add((req, res, dto) => {
var profiler = RequestProfiler.GetProfiler(req);
using (profiler.Step("Very slow step")) {
Thread.Sleep(1000);
}
});
GlobalResponseFilters.Add((req, res, dto) => RequestProfiler.Stop(req));

Can I or Should I use a Global variable in Angularjs to store a logged in user?

I'm new to angular and developing my first 'real' application. I'm trying to build a calendar/scheduling app ( source code can all be seen on github ) and I want to be able to change the content if there is a user logged in (i.e. display details relevant to them) but here's the catch:
I don't want the app to be dependent on having a logged in user ( needs to be something that can be configured to work publicly, privately or both)
I don't want to implement the user/login within this app if it can be avoided ( I want to eventually include my app in another app where this might be implemented but isn't necessarily implemented using any particular security frameworks or limited to any)
I had an idea of creating some global variable user that could be referenced through out my application, or if I had to implement a system to do it all in this app that I could do so in in some abstract way so that different options could be injected in.
some of my ideas or understanding of what I should be doing may be completely wrong and ignorant of fundamentals but I genuinely do not know what approach I should take to do this.
In case it is relevant I currently don't have any back-end but eventually hope use MongoDB for storage and nodejs for services but I also want to try keep it open-ended to allow others to use different storage/backends such as sql and php
is there away to have a global uservariable/service that I could inject/populate from another (parent?) app?
If so what would be the best approach to do so?
If Not, why and what approach should I take and why?
Update
I Believe from comments online and some suggestion made to me that a service would be the best option BUT How would I go about injecting from a parent application into this applications service?
If your (single) page is rendered dynamically by the server and the server knows if you are logged-in or not, then you could do the following:
Dynamically render a script tag that produces:
<script>
window.user = { id: 1234, name: 'User A', isLoggedIn: true };
</script>
For non logged-in users:
<script>
window.user = { isLoggedIn: false };
</script>
For convinience, copy user to a value inside angular's IOC:
angular.module('myApp').value('user', window.user);
Then, you can use it in DI:
angular.module('myApp').factory('myService', function(user) {
return {
doSomething: function() {
if (user.isLoggedIn) {
...
} else {
...
}
}
};
});
Something tricky (which you should thing twice before doing [SEE COMMENTS]) is extending the $scope:
angular.module('myApp').config(function($provide) {
$provide.decorator('$controller', function($delegate, user) {
return function(constructor, locals) {
locals.$scope._user = user;
return $delegate(constructor, locals);
};
});
});
This piece of code decorates the $controller service (responsible for contructing controllers) and basically says that $scope objects prior to being passed to controllers, will be enhanced with the _user property.
Having it automatically $scoped means that you can directly use it any view, anywhere:
<div ng-if="_user.isLoggedIn">Content only for logged-in users</div>
This is something risky since you may end up running into naming conflicts with the original $scope API or properties that you add in your controllers.
It goes without saying that these stuff run solely in the client and they can be easily tampered. Your server-side code should always check the user and return the correct data subset or accept the right actions.
Yes you can do it in $rootScope. However, I believe it's better practice to put it inside a service. Services are singletons meaning they maintain the same state throughout the application and as such are prefect for storing things like a user object. Using a "user" service instead of $rootScope is just better organization in my opinion. Although technically you can achieve the same results, generally speaking you don't want to over-populate your $rootScope with functionality.
You can have a global user object inside the $rootScope and have it injected in all your controllers by simply putting it into the arguments of the controller, just as you do with $scope. Then you can implement functionalities in a simple check: if($rootScope.user). This allows you to model the user object in any way you want and where you want, acting as a global variable, inside of Angular's domain and good practices with DI.
Just to add on my comment and your edit. Here is what the code would look like if you wanted to be able to re-use your user service and insert it into other apps.
angular.module('user', []).service('userService', [function(){
//declare your user properties and methods
}])
angular.module('myApp', ['user'])
.controller('myCtrl', ['userService', '$scope', function(userService, scope){
// you can access userService from here
}])
Not sure if that's what you wanted but likewise you could have your "user" module have a dependency to another "parent" module and access that module's data the same way.

Resources