Is there a way to view logging of my Azure Function App without the use of Application Insights?
Can I write the logging of my Function app to a separate file that I can view? (edit) If so, how?
Edit: I should have mentioned that I am using Java.
Diagnostic Settings will be of help here. You can enable diagnostics to publish the logs to a storage account.
To set the settings. Search for Diagnostic settings in the search-pane of your function app.
And then enable by providing the storage account details:
For full information refer: https://learn.microsoft.com/en-us/azure/azure-functions/functions-monitor-log-analytics?tabs=java
The benefit of this is: that you can continue to log using the default logging framework that the azure-functions provide. There isn't any code change that is required.
yes, I do agree with the point mentioned by #Thiago Custodio. you can use serilog in the Azure functions to view your logs.
Here is the code provided by #Ivan Yang in this So for using Serilg in Azure functions.
[assembly: WebJobsStartup(typeof(Startup))]
namespace MyApp
{
public class Startup : IWebJobsStartup
{
public void Configure(IWebJobsBuilder builder)
{
//other code
builder.Services.AddLogging();
}
}
public class Functions
{
//other code
private ILogger _log;
public Functions(ILoggerFactory loggerFactory)
{
_log = loggerFactory.CreateLogger<Functions>();
}
[FunctionName("Token")]
public async Task<IActionResult> Function1(
[HttpTrigger()]...)
{
_log.LogInformation("Function1 invoked");
}
}
}
Related
I am looking to disable the swagger functionality / endpoint in a production environment based on a config value.
How would I go about this?
I believe the best way to achieve this is not to add the bundle during the execution of the initialize method when a DropWizard application first starts.
The issue with this solution is that you cannot access the configuration get methods that are populated from the values in the YAML/YML file. These values are available are available when we the application gets to the run method.
Here is my initialise method from the application class
#Override
public void initialize(Bootstrap<Configuration> bootstrap) {
LOGGER.debug("initialize");
bootstrap.setConfigurationSourceProvider(new SubstitutingSourceProvider(bootstrap.getConfigurationSourceProvider(),
new EnvironmentVariableSubstitutor(false)));
bootstrap.addBundle(new SwaggerBundle<Configuration>() {
#Override
protected SwaggerBundleConfiguration getSwaggerBundleConfiguration(Configuration configuration) {
return configuration.swaggerBundleConfiguration;
}
});
}
If I need to clarify more please let me know.
Thanks in advance.
You can set an environment variable in production and use it to decide whether to include SwaggerBundle or not. For example:
if (!"prod".equalsIgnoreCase(System.getenv("ENVIRONMENT"))) {
bootstrap.addBundle(new SwaggerBundle<Configuration>() { ... }
}
I was using an older version of DropWizard at the time.
After updating, there were new methods available including setIsEnabled()
This is what was added to solve the issue.
bootstrap.addBundle(new SwaggerBundle<Configuration>() {
#Override
protected SwaggerBundleConfiguration getSwaggerBundleConfiguration(Configuration configuration) {
if(!configuration.getSwaggerEnabled()){
configuration.swaggerBundleConfiguration.setIsEnabled(false);
}
return configuration.swaggerBundleConfiguration;
}
});
}
Thanks,
I have essentially the same question as here but am hoping to get a less vague, more informative answer.
I'm looking for a way to configure DropWizard programmatically, or at the very least, to be able to tweak configs at runtime. Specifically I have a use case where I'd like to configure metrics in the YAML file to be published with a frequency of, say, 2 minutes. This would be the "normal" default. However, under certain circumstances, I may want to speed that up to, say, every 10 seconds, and then throttle it back to the normal/default.
How can I do this, and not just for the metrics.frequency property, but for any config that might be present inside the YAML config file?
Dropwizard reads the YAML config file and configures all the components only once on startup. Neither the YAML file nor the Configuration object is used ever again. That means there is no direct way to configure on run-time.
It also doesn't provide special interfaces/delegates where you can manipulate the components. However, you can access the objects of the components (usually; if not you can always send a pull request) and configure them manually as you see fit. You may need to read the source code a bit but it's usually easy to navigate.
In the case of metrics.frequency you can see that MetricsFactory class creates ScheduledReporterManager objects per metric type using the frequency setting and doesn't look like you can change them on runtime. But you can probably work around it somehow or even better, modify the code and send a Pull Request to dropwizard community.
Although this feature isn't supported out of the box by dropwizard, you're able to accomplish this fairly easy with the tools they give you. Note that the below solution definitely works on config values you've provided, but it may not work for built in configuration values.
Also note that this doesn't persist the updated config values to the config.yml. However, this would be easy enough to implement yourself simply by writing to the config file from the application. If anyone would like to write this implementation feel free to open a PR on the example project I've linked below.
Code
Start off with a minimal config:
config.yml
myConfigValue: "hello"
And it's corresponding configuration file:
ExampleConfiguration.java
public class ExampleConfiguration extends Configuration {
private String myConfigValue;
public String getMyConfigValue() {
return myConfigValue;
}
public void setMyConfigValue(String value) {
myConfigValue = value;
}
}
Then create a task which updates the config:
UpdateConfigTask.java
public class UpdateConfigTask extends Task {
ExampleConfiguration config;
public UpdateConfigTask(ExampleConfiguration config) {
super("updateconfig");
this.config = config;
}
#Override
public void execute(Map<String, List<String>> parameters, PrintWriter output) {
config.setMyConfigValue("goodbye");
}
}
Also for demonstration purposes, create a resource which allows you to get the config value:
ConfigResource.java
#Path("/config")
public class ConfigResource {
private final ExampleConfiguration config;
public ConfigResource(ExampleConfiguration config) {
this.config = config;
}
#GET
public Response handleGet() {
return Response.ok().entity(config.getMyConfigValue()).build();
}
}
Finally wire everything up in your application:
ExampleApplication.java (exerpt)
environment.jersey().register(new ConfigResource(configuration));
environment.admin().addTask(new UpdateConfigTask(configuration));
Usage
Start up the application then run:
$ curl 'http://localhost:8080/config'
hello
$ curl -X POST 'http://localhost:8081/tasks/updateconfig'
$ curl 'http://localhost:8080/config'
goodbye
How it works
This works simply by passing the same reference to the constructor of ConfigResource.java and UpdateConfigTask.java. If you aren't familiar with the concept see here:
Is Java "pass-by-reference" or "pass-by-value"?
The linked classes above are to a project I've created which demonstrates this as a complete solution. Here's a link to the project:
scottg489/dropwizard-runtime-config-example
Footnote: I haven't verified this works with the built in configuration. However, the dropwizard Configuration class which you need to extend for your own configuration does have various "setters" for internal configuration, but it may not be safe to update those outside of run().
Disclaimer: The project I've linked here was created by me.
I solved this with bytecode manipulation via Javassist
In my case, I wanted to change the "influx" reporter
and modifyInfluxDbReporterFactory should be ran BEFORE dropwizard starts
private static void modifyInfluxDbReporterFactory() throws Exception {
ClassPool cp = ClassPool.getDefault();
CtClass cc = cp.get("com.izettle.metrics.dw.InfluxDbReporterFactory"); // do NOT use InfluxDbReporterFactory.class.getName() as this will force the class into the classloader
CtMethod m = cc.getDeclaredMethod("setTags");
m.insertAfter(
"if (tags.get(\"cloud\") != null) tags.put(\"cloud_host\", tags.get(\"cloud\") + \"_\" + host);tags.put(\"app\", \"sam\");");
cc.toClass();
}
I have in place a spring security ACL system, and it seems to work fine, only that I `m not sure how should I perform a permission check programmatically.
My app is split into 3 layers (View,Service(Business),DAO) and I want to perform the auth in the Service layer. So, for a method that take as an argument a domain object :
#PreAuthorize("hasPermission(#proj,'write'")
public Project updateProject(Project proj) {
.............
}
the problem is solved with annotations.
But for a method that take as an argument an object that does not have an acl on it I have to programmatically check if user has permission.
Let`s say i have an object ProjectWrapper:
public class ProjectWrapper {
private Project project;
private Something something;
// setters and getters here
}
so now my Service method received this type of argument:
public Project updateProject(ProjectWapper projWrapp) {
Project p = projWrapp.getProject();
// before performing any operation on project I need to know if current user has neccessary permissions on this object
// ??? how do i check that ?
}
Do i need to use AclService to perform that ? just like when I need to create/update a permission, or is there an cleaner/nicer possibility ?
The same question for deleteProject(Long id) methods,as first i have to get the object from db to check if the current user has delete permission.
Method security annotations support Spring EL expressions. In case of your wrapper class, you can use it as follows.
#PreAuthorize("hasPermission(#projectWrapper.project, 'write'")
public Project updateProject(ProjectWrapper projectWrapper) {
// body omitted
}
And if you have just an object identifier instead of the actual object, you can use pattern below.
#PreAuthorize("hasPermission(#id, 'my.package.Project' 'delete'")
public void deleteProject(Long id) {
// body omitted
}
You may need to adjust default configuration (e.g. strategy to retrieve object identity and the like) to meet you requirements. See org.springframework.security.acls.AclPermissionEvaluator class for more details.
I have an Android application with several "Log.d" calls along the code in order to following the events of the app.
In order to enable or disable the debug messages I call the Log with
if (MyApp.debug) Log.d("Doing something");
Where MyApp.debug is a final boolean that I change before compiling.
Now I want to use some classes from the application as a library for another app, so I copied them into a new library project. The problem is that now in the library I have no a MyApp class.
How can I make something similar for controlling from the app if the library must print the debug messages or not?
Thanks in advance
I'd suggest placing the variable inside a static class called Log, which you could then, at runtime, have checking a static boolean variable to figure out if it should log or not.
That way, you still have the convenience, but it's all contained inside the logger.
For example:
public class Log {
public static boolean mustLog = false;
// methods etc.
}
Then, in your app, just use if(Log.mustLog) ...
Hope that helps.
You can create a different custom class in your library
public Class LogPrefs
{
public static final boolean enabled = true;
}
and set it on and off as you need. Then just
if (LogPrefs.enabled) Log.d("Doing something");
I always erase debug messages as I go, since they tend to clutter the screen. I keep however Info and Error messages; eventually they can be recovered and sent back after a crash.
Before I reinvent the wheel - I want to be able to insert debugging traces in my code, such as say("We are here.");, without defining static void say() in every class. It needs to do System.out.println(s), and to be globally switched on or off (doSay(false)), and I'd also like it to be able to identify the class from which it's being invoked (as described here). For example:
MyClass: We are here.
Does Java already have such a tool?
Use SLF4j, not log4j (at least, not directly). They are both created by the same author, Ceki Gülcü, but SLF4J incorporates knowledge gained by seeing log4j in use, and looking at advances in other logging packages.
SLF4J is a common API for a number of different underlying logging systems, like log4j, the java.util.logging package, etc. It also has its own "native" implementation, logback.
One reason I like it better than log4j is its support for message templates. These keep your code simpler.
Also, it allows me to include logging in a library, but let the user of my library choose the logging implementation. Without something like this, a user might have to configure logging just for my library, and it wouldn't be unified with the rest of his application.
The most popular Java logging framework is Log4J which does this (and much more).
Look here for a list of other.
Yes. It's called a logging framework. Java has java.util.logging. But many prefer using Log4J.
You could use a logger like Apache's Log4J and do something like logger.trace("We are here");. When you want that off, set the log level higher (debug, warn, error) in your configuration and the trace logs will disappear.
Java has more advanced logging tools, like log4j or logback. There you should create a public static final Logger logger = Logger.getLogger(..) and use the logger to write debug/info/warn/error messages to wherever you like. They are highly configurable - what and where to log.
For the simpler case (if this is a toy project), you can simply define a class with the public static void log(..) method and use it from every class.
Why not static-declare a function in your Main.java, and use it allround?
public class Main {
private static boolean debug;
public static void setDebug(boolean d) { Main.debug = d; }
public static void say(String s) { if(Main.debug) System.out.println(s); }
}
Let me know if this fits your needs.
Edit: revised the code
I didn't know about static import! I combined ideas from #ninetwozero, #karl, and #erickson to create this:
package myPkg;
public class CLHUtilities {
private static boolean saying = false;
public static void tracing(boolean b) {
saying = b;
}
/*
* Technique taken from:
* http://stackoverflow.com/questions/282977/which-class-invoked-my-static-method
*/
public static void say(String s) {
if (saying) {
Throwable t = new Throwable();
StackTraceElement[] trace = t.getStackTrace();
String className = trace[1].getClassName();
String whoCalledMe = null;
try {
whoCalledMe = Class.forName(className).getSimpleName();
} catch (Exception e) {
}
System.out.println(whoCalledMe + ": " + s);
}
}
}
which can be used simply as:
import static myPkg.CLHUtilities.*;
:
tracing(true);
:
say("We are here.");
Which suits my needs perfectly.