Erlang store initial application configuration - erlang

I am working on a monitoring app and I have to pass in at startup some initial configuration which consists of a couple of lists of IP addresses. What's the OTP way to pass this data to the application - through the .app file or is there any other general accepted way?

Use an Erlang configuration file:
A configuration file contains values for configuration parameters for
the applications in the system. The erl command line argument -config
Name tells the system to use data in the system configuration file
Name.config.
Configuration parameter values in the configuration file will override
the values in the application resource files (see app(4)). The values
in the configuration file can be overridden by command line flags (see
erl(1)).
The value of a configuration parameter is retrieved by calling
application:get_env/1,2.
If you need to override them at runtime, you can use application:set_env/3, but with care.

you can handle configuration in several ways.
here a link to another stackoverflow topic
IMHO i suggest .app file, or you can use a configuration file (here another link to stackoverflow topic)

I would create a name gen_server process that has a list of ip addresses as it's state. In the init of the server a predefined list would be read from a file using file:consult and used as the initial state of the server. To get the list of ip addresses from this named gen_server, a handle_call(get_ip, _From, State) needs to be implemented.
This way you prevent shared global state, which gives you great Erlang karma, and have a better starting point for added functionality like runtime ip address changes.

Use a file in which you have your data as erlang terms. However you need to protect the file. Reading from the file at start up use: file:consult/1. If modification of the file will occur by the user or system administrator, use the following functions to protect or refuse access to the file:
-include_lib("kernel/include/file.hrl").
protect_file(File)->
{_,File_info} = file:read_file_info(File),
file:write_file_info(File,File_info#file_info{access = read,mode = 33060}).
unprotect_file(File)->
{_,File_info} = file:read_file_info(File),
file:write_file_info(File,File_info#file_info{access = read_write,mode = 33206}).
Use function protect_file/1 to make the file read-only. If you need to make the file writable then modify using unprotect_file/1. A file with erlang terms is easier because you do not need parsing.You could also write you configurations as JSON objects or XML data into a file. In summary, using a file for all you configs will be better managed by your application and those who interact with it. An example is the ejabberd.cfg file, the config file for ejabberd server. Its easiest with a file with erlang terms because you can comment here and there for the system administrator to see other available options about a certain configuration.

Related

Get Current Serilog Configuration to know full write-to file path

We are trying to switch completely from log4net to Serilog. However, this part of functionality seems to be missing. What I need is to be able to get location of log-files Inside a library class. This is important for our Desktop Click-Once application because that location is different on different OSes and for different users. When user needs access to the logs we can direct him to the proper folder.
Very similar question was asked here:
Read current Serilog's configuration
But I can't believe that there is no way to get this information from Serilog. I don't need to change that configuration - just read it. In log4net we could do:
log4net.LogManager.GetAllRepositories()
and then
repository.Root.Appenders.OfType<FileAppender>
Please tell me that there is some kind back-door to the current LoggerConfiguration or if there is some alternative way to get file-path of the current File-Sink.
Serilog does not expose the list of Sinks that have been configured, so your only option at the moment would be to use Reflection if you really want to get this information from the live Serilog configuration.
You can see an example on this answer:
Unit test Serilog configuration
That said, given all you want to do is to know the path where log files are being written, that's something you can easily store at the start of the application at the moment you set up your Serilog logging pipeline.
If you configure the file path in code, you can store that information in a static property somewhere your entire app can access. If you get your folder path from the appSettings.json or App.config, you can read the information from there.
If you have environment variables in your configuration you can get the same values that Serilog gets by expanding these environment variables e.g. Environment.ExpandEnvironmentVariables("%LogPath%\\AppName.log")

Change the Values of the app config file in a windows service through another program

I have a windows service which downloads some files from SFTP and uploads it to database and generates PDf's from that data. So now when i should give the executable files to my client i think he need to change the app config file like sftp details and the pdf paths. So i am just thinking about a program like a windows forms or a console which reads the input and save those in app config file. Is it possible like and by the way i have created a setup project for the windows service where he gets 2 files .msi file and setup file. Is it possible to achieve the above problem in this case ?
If I understand correctly, you're wanting some kind of UI application that allows the user to configure the operation of the Windows service. This is certainly possible as I've been doing it for several years now. However, you don't want to do this via the app.config file. The app.config file is read by the Windows service when it starts up, so any changes made to it would go unnoticed until the service restarts. A better course of action would be to communicate the changes to the service via the Windows Communication Foundation (or some other ICP mechanism, e.g., pipes, sockets, shared memory, etc.). I've managed to use this successfully, although to be honest, I'm using ordinary sockets now. In any case, the service would basically "listen" for incoming configuration messages, "read" those messages, and then "configure" itself accordingly, perhaps even saving the changes in its app.config file so the changes are preserved for when the service restarts later.
HTH

F# web service data provider with local wsdl file

I am trying to write F# client for our web services. The example here looks very good except it uses the server url in the code.
type TerraService = WsdlService<"http://msrmaps.com/TerraService2.asmx?WSDL">
This prevents me from reading service url from configuration file at run time, and make deployment from dev server to production server difficult.
I am wondering if there is any WSDL provider that works similar to Dbml Provider
I'm not sure I understand exactly what you're looking for, but note that the URL provided as a static parameter is used to generate types, but if desired a different URL can be provided at runtime by using a different overload of the Get...Soap method. This URL can come from wherever you want (e.g. you can read it from a config file if that's your scenario). E.g.:
type TerraService = WsdlService<"http://msrmaps.com/TerraService2.asmx?WSDL">
let terraClient = TerraService.GetTerraServiceSoap(EndpointAddress(myRuntimeUrl))
Nothing currently exists that does that but the code is open source so you could make a version of it that work's in the mode that you desire:1 2.

DART: What is best practice for config settings

Interpreted languages such as PHP allow a separate file, often called config.php, to contain string constants such as server names. This facilitates deployment, as the config file is simply not uploaded when the code is updated - the server names, e.g. for REST transactions, are typically different in the deployment environment.
In Dart, since it is compiled, this approach does not work. If there are server name constants which are referred to in the HTML via {{ }}, it seems the code must be recompiled before deployment.
Is there a way to specify string constants in such a way to avoid this recompilation requirement?
There are a couple of options I can think of:
One trick is to put configuration in a map keyed by hostname. At runtime, look up the configuration from the map, using window.location as a key. This will allow configuration to be baked into the Dart source, yet still allow different values to be specified for different environments.
If you want to be able to change your configuration after compilation, you can embed it as JSON within the HTML source, or load it via an HTTP request. (This isn't using a constant as asked, however, by definition it's not possible to change a constant after compile time)
Ok, so short answer is "You can't" - at the moment. But the Dart team are aware of this limitation, and are discussing it in dartlang as per the comment above.

External commands in a controller

I have various files of extensions .cpp stored on the server. When user clicks on the compile button, I should run gcc command passing the absolute path of the file to gcc compiler and then show the user the output of the file.
How can i do that???
Kernel.system may the command that you are looking for: it calls a system process. For example:
if (system("gcc ..."))
#output_to_show = %x['./compiled']
end
Assuming that your server is in Linux/UNIX, it would be good to separate the compile&execute process from the website server in order to reduce the security risks (by creating a new user just for this purpose). Or can you trust the content of the cpp-Files?

Resources