LOG4J2 Use multiple config files using java - java

can log4j2 use multiple config files. I wanna run my project and load one default config file - logger.xml and after that to check if there is a second configuration from another file logger_1.xml and to add it and not to override the first one.
Here is some dummy code. In short I wanna fill up the arrayList with file paths and then to load all of them.
public class LoggerConfiguratorManager
{
public static final String LOG4J_PATH = "etc/confs/logger.xml";
private static LoggerContext context = null;
private static final ConfigurationFactory factory = XmlConfigurationFactory.getInstance();
private static ConfigurationSource configurationSource = null;
private static Configuration configuration = null;
private static final ArrayList<String> registred_logger = new ArrayList<>();
private static void loadLoggerConfig(String logger_path)
{
InputStream is = null;
try
{
if(logger_path.endsWith(".xml"))
is = new FileInputStream(logger_path);
else
{
final ZipFile archive = new ZipFile(logger_path);
final ZipEntry logger_entry = archive.getEntry(LOG4J_PATH);
if(logger_entry == null) throw new IOException("Cannot find 'logger.xml' in " + logger_path);
is = archive.getInputStream(logger_entry);
}
configurationSource = new ConfigurationSource(is);
configuration = factory.getConfiguration(configurationSource);
}
catch(IOException ex)
{
System.err.println("=============================================================================");
System.err.println("=============================== LOGGER CONFIG ===============================");
System.err.println("=============================================================================");
System.err.println("=== [ERROR] " + ex);
}
finally
{
if (configurationSource != null)
{
context = Configurator.initialize(null, configurationSource);
context.start(configuration);
try { is.close(); } catch(IOException ex) { }
}
}
}
public static void load()
{
registred_logger.add(Globals.getClassLocation(LoggerConfiguratorManager.class));
for(final String conf : registred_logger)
loadLoggerConfig(conf);
}
public static void regLoggerConf(String conf_path) { registred_logger.add(conf_path); }

I would suggest doing instead:
public class LoggerConfiguratorManager {
private static final String LOG4J_PATH = "etc/confs/log4j2.xml";
private static final StringBuffer paths = new StringBuffer(LOG4J_PATH);
public static void registerConfiguration(String confPath) {
paths.append(",").append(confPath);
}
public static void initLog4j() {
Configurator.initializer("My Config", null, paths.toString(), null);
}
}
For a full working example please see https://github.com/rgoers/CompositeConfigurationExample.

Related

How to generate .dot file using Schemacrawler

Using schemcrawler I've generated html file
public final class ExecutableExample {
public static void main(final String[] args) throws Exception {
// Set log level
new LoggingConfig(Level.OFF);
final LimitOptionsBuilder limitOptionsBuilder = LimitOptionsBuilder.builder()
.includeSchemas(new IncludeAll())
.includeTables(new IncludeAll());
final LoadOptionsBuilder loadOptionsBuilder =
LoadOptionsBuilder.builder()
// Set what details are required in the schema - this affects the
// time taken to crawl the schema
.withSchemaInfoLevel(SchemaInfoLevelBuilder.standard());
final SchemaCrawlerOptions options =
SchemaCrawlerOptionsBuilder.newSchemaCrawlerOptions()
.withLimitOptions(limitOptionsBuilder.toOptions())
.withLoadOptions(loadOptionsBuilder.toOptions());
final Path outputFile = getOutputFile(args);
final OutputOptions outputOptions =
OutputOptionsBuilder.newOutputOptions(TextOutputFormat.html, outputFile);
final String command = "schema";
try (Connection connection = getConnection()) {
final SchemaCrawlerExecutable executable = new SchemaCrawlerExecutable(command);
executable.setSchemaCrawlerOptions(options);
executable.setOutputOptions(outputOptions);
executable.setConnection(connection);
executable.execute();
}
System.out.println("Created output file, " + outputFile);
}
private static Connection getConnection() {
final String connectionUrl = "jdbc:postgresql://localhost:5433/table_accounts";
final DatabaseConnectionSource dataSource = new DatabaseConnectionSource(connectionUrl);
dataSource.setUserCredentials(new SingleUseUserCredentials("postgres", "new_password"));
return dataSource.get();
}
private static Path getOutputFile(final String[] args) {
final String outputfile;
if (args != null && args.length > 0 && !isBlank(args[0])) {
outputfile = args[0];
} else {
outputfile = "./schemacrawler_output.html";
}
final Path outputFile = Paths.get(outputfile).toAbsolutePath().normalize();
return outputFile;
}
But I want to have an output in .dot file that contains diagram, node, graph, edge etc.. So how can I do it using my code or maybe some another way to do it with Java?
Simply change the output format from TextOutputFormat.html to DiagramOutputFormat.scdot.
Sualeh Fatehi, SchemaCrawler

Create a simple job spring boot

I created a spring boot project.
I use spring data with elastic search.
The whole pipeline: controller -> service -> repository is ready.
I now have a file that represents country objects (name and isoCode) and I want to create a job to insert them all in elastic search.
I read the spring documentation and I find that there's too much configuration for such a simple job.
So I'm trying to do a simple main "job" that reads a csv, creates objects and insert them in elastic search.
But I have a bit of trouble to understand how injection would work in this case:
#Component
public class InsertCountriesJob {
private static final String file = "D:path\\to\\countries.dat";
private static final Logger LOG = LoggerFactory.getLogger(InsertCountriesJob.class);
#Autowired
public CountryService service;
public static void main(String[] args) {
LOG.info("Starting insert countries job");
try {
saveCountries();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void saveCountries() throws Exception {
try (CSVReader csvReader = new CSVReader(new FileReader(file))) {
String[] values = null;
while ((values = csvReader.readNext()) != null) {
String name = values[0];
String iso = values[1].equals("N") ? values[2] : values[1];
Country country = new Country(iso, name);
LOG.info("info: country: {}", country);
//write in db;
//service.save(country); <= can't do this because of the injection
}
}
}
}
based on Simon's comment. Here's how I resolved my problem. Might help people that are getting into spring, and that are trying not to get lost.
Basically, to inject anything in Spring, you'll need a SpringBootApplication
public class InsertCountriesJob implements CommandLineRunner{
private static final String file = "D:path\\to\\countries.dat";
private static final Logger LOG = LoggerFactory.getLogger(InsertCountriesJob.class);
#Autowired
public CountryService service;
public static void main(String[] args) {
LOG.info("STARTING THE APPLICATION");
SpringApplication.run(InsertCountriesJob.class, args);
LOG.info("APPLICATION FINISHED");
}
#Override
public void run(String... args) throws Exception {
LOG.info("Starting insert countries job");
try {
saveCountry();
} catch (Exception e) {
e.printStackTrace();
}
LOG.info("job over");
}
public void saveCountry() throws Exception {
try (CSVReader csvReader = new CSVReader(new FileReader(file))) {
String[] values = null;
while ((values = csvReader.readNext()) != null) {
String name = values[0];
String iso = values[1].equals("N") ? values[2] : values[1];
Country country = new Country(iso, name);
LOG.info("info: country: {}", country);
//write in db;
service.save(country);
}
}
}
}

How read JSON file in Play framework using Java

I am trying to read JSON file from test/resources package in my play application. I am getting com.couchbase.client.java.error.DocumentDoesNotExistException. I believe my path is not correct, can anyone suggest how to take absolute path?
public class AppControllerTest extends WithApplication {
#Inject
AppDaoServiceImpl appDaoServiceImpl;
private CouchbaseEnvironment env;
private static Cluster cluster = null;
private static Bucket bucket = null;
private String testResources = System.getProperty("java.class.path") + "/test/resources/";
private static final ALogger logger = Logger.of(AppControllerTest.class);
#Rule
public ExpectedException thrown = ExpectedException.none();
#Override
protected Application provideApplication() {
return new GuiceApplicationBuilder().build();
}
#Before
public void init() {
env = DefaultCouchbaseEnvironment.create();
cluster = CouchbaseCluster.create(env, "127.0.0.1:8091");
bucket = cluster.openBucket("CLUSTER", "admin123");
try {
String docId = "ABEBV_common";
File testResource = new File(testResources + "ABEBV_common.json");
FileInputStream is = new FileInputStream(testResource);
JsonNode testData = Json.parse(is);
RawJsonDocument rawJsonDocument = RawJsonDocument.create(docId, testData.asText());
bucket.upsert(rawJsonDocument);
} catch (Exception e) {
}
}
#Test
public void testGenericData() {
Http.RequestBuilder request = new Http.RequestBuilder().method(GET).uri("/app/ms/genericdata/ABEBV")
.header("client_id", "chase");
Result result = route(app, request);
assertEquals(OK, result.status());
assertEquals("application/json", result.contentType().get());
assertTrue(contentAsString(result).contains("141-GYCVZY"));
}
#After
public void deleteDocuments() {
bucket.remove("ABEBV_common");
bucket.close();
cluster.disconnect();
}
}
Yes your path is not correct, System.getProperty("java.class.path") will return all the java class path the jvm is referring to You have to, instead use "user.dir".
private String testResources = System.getProperty("user.dir") + "/test/resources/";

loop to check if a file exists

I have a folder that must contain always one file config8, and if a new file is created in this folder the old file is deleted and replaced by the new file with the same name config8.
I write this code
File file1 = new File("/home/olfa/Bureau/config/config8");
File file2 = new File("/home/olfa/Bureau/config/config9");
while (file2.exists())
{
file1.delete();
file2.renameTo(file1); }
}
serverConnection = new ServerConnection("/home/olfa/Bureau/config/config8");
I need to add a loop to check everytime if config9 is created.
Instead of a loop try a WatchService.
Basically you would be watching a particular directory for change and then you can react on this change.
https://docs.oracle.com/javase/tutorial/essential/io/notification.html
For example :
import static java.nio.file.StandardWatchEventKinds.*;
WatchService watcher = FileSystems.getDefault().newWatchService();
Path dir = ...;
try {
WatchKey key = dir.register(watcher,
ENTRY_CREATE,
ENTRY_DELETE,
ENTRY_MODIFY);
} catch (IOException x) {
System.err.println(x);
}
Then you can process your key events.
If you have to solve this task with Java 1.6, you can use https://commons.apache.org/proper/commons-vfs/, version 2.1.
Here is an example for moving all incoming config files to "config8":
import org.apache.commons.vfs2.*;
import org.apache.commons.vfs2.impl.DefaultFileMonitor;
import java.io.File;
public class ConfigWatcher {
private static final String configDirName = "target/config";
private static final String configName = "config8";
private static final String absoluteConfigName = new File(configDirName + File.separator + configName).getAbsolutePath();
private FileSystemManager manager = null;
FileObject configDir = null;
private FileObject configFile = null;
private FileChangeEvent lastEvent = null;
public void watchConfig() throws Exception {
manager = VFS.getManager();
DefaultFileMonitor fm = new DefaultFileMonitor(new ConfigFileListener());
configFile = manager.resolveFile(absoluteConfigName);
configDir = manager.resolveFile(new File(configDirName).getAbsolutePath());
fm.setDelay(1000);
fm.addFile(configDir);
fm.start();
}
class ConfigFileListener implements FileListener {
public void fileCreated(FileChangeEvent fileChangeEvent) throws Exception {
FileObject latestConfigFile = fileChangeEvent.getFile();
String fileBaseName = fileChangeEvent.getFile().getName().getBaseName();
if (!configName.endsWith(fileBaseName) && !fileChangeEvent.equals(lastEvent)) {
System.out.println("new config detected - move config");
latestConfigFile.moveTo(configFile);
}
lastEvent = fileChangeEvent;
}
public void fileChanged(FileChangeEvent fileChangeEvent) {
}
public void fileDeleted(FileChangeEvent fileChangeEvent) {
}
}
public static void main(String[] args) throws Exception {
final ConfigWatcher configWatcher = new ConfigWatcher();
configWatcher.watchConfig();
while (true) {
Thread.sleep(1000);
}
}
}

Read json file and how to change hard coding path

Question : I want to change the hard coding json file path. The path will be from detailsListHM but I dont know how to do it.
Here is my main program
public class Program {
// hard coding json file path
private static final String filePath = "C:/appSession.json";
public static void main(String[] args)
{
taskManager();
}
public static void taskManager()
{
detailsHM = jsonParser(filePath);
}
public static HashMap<String, String> jsonParser(String jsonFilePath)
{
HashMap<String, String> detailsHM = new HashMap<String, String>();
String refGene = "";
try {
// read the json file
FileReader reader = new FileReader(filePath);
} catch (FileNotFoundException ex) {
ex.printStackTrace();
}
}
}
Here is another class called CustomConfiguration
public class CustomConfiguration {
private static HashMap<String, String> detailsListHM =new HashMap<String,String>();
public static void readConfig(String a) {
//read from config.properties file
try {
String result = "";
Properties properties = new Properties();
String propFileName = a;
InputStream inputStream = new FileInputStream(propFileName);
properties.load(inputStream);
// get the property value and print it out
String lofreqPath = properties.getProperty("lofreqPath");
String bamFilePath = properties.getProperty("bamFilePath");
String bamFilePath2 = properties.getProperty("bamFilePath2");
String resultPath = properties.getProperty("resultPath");
String refGenPath = properties.getProperty("refGenPath");
String filePath = properties.getProperty("filePath");
Set keySet = properties.keySet();
List keyList = new ArrayList(keySet);
Collections.sort(keyList);
Iterator itr = keyList.iterator();
while (itr.hasNext()) {
String key = (String) itr.next();
String value = properties.getProperty(key.toString());
detailsListHM.put(key, value);
}
} catch (IOException ex) {
System.err.println("CustomConfiguration - readConfig():" + ex.getMessage());
}
}
public static HashMap<String, String> getConfigHM() {
return detailsListHM;
}
Add a new property call "json-filepath" and read like
String filePath = properties.getProperty("json-filepath");
So the end user can change the json file path even during the runtime.
you can pass the filePath parameter by using the main parameters.
public static void main(String[] args) {
String filePath = null;
if(args.length > 0) {
filePath = args[0];
}
}
And invoke your main class like this:
java Program C:/appSession.json

Categories

Resources