Порядок, в котором связаны библиотеки, имеет значение, если библиотеки зависят друг от друга. В общем случае, если библиотека A
зависит от библиотеки B
, тогда libA
ДОЛЖЕН появляться перед libB
в флагах компоновщика.
Например:
// B.h
#ifndef B_H
#define B_H
struct B {
B(int);
int x;
};
#endif
// B.cpp
#include "B.h"
B::B(int xx) : x(xx) {}
// A.h
#include "B.h"
struct A {
A(int x);
B b;
};
// A.cpp
#include "A.h"
A::A(int x) : b(x) {}
// main.cpp
#include "A.h"
int main() {
A a(5);
return 0;
};
Создайте библиотеки:
$ g++ -c A.cpp
$ g++ -c B.cpp
$ ar rvs libA.a A.o
ar: creating libA.a
a - A.o
$ ar rvs libB.a B.o
ar: creating libB.a
a - B.o
Скомпилируйте:
$ g++ main.cpp -L. -lB -lA
./libA.a(A.o): In function `A::A(int)':
A.cpp:(.text+0x1c): undefined reference to `B::B(int)'
collect2: error: ld returned 1 exit status
$ g++ main.cpp -L. -lA -lB
$ ./a.out
Чтобы повторить снова, порядок имеет значение!
slf4j - это только API. У вас должна быть конкретная реализация (например, log4j). Эта конкретная реализация имеет конфигурационный файл, в котором указывается, где хранить журналы.
[/g1]
Когда slf4j ловит сообщения журнала с регистратором, оно дается к приложению, которое решает, что делать с сообщением. По умолчанию ConsoleAppender отображает сообщение в консоли.
Файл конфигурации по умолчанию:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<!-- By default => console -->
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
Если вы поместите файл конфигурации в путь к классам, то ваша конкретная реализация (в вашем случае log4j) найдет и использует его. См. документацию Log4J.
Пример файла appender:
<Appenders>
<File name="File" fileName="${filename}">
<PatternLayout>
<pattern>%d %p %C{1.} [%t] %m%n</pattern>
</PatternLayout>
</File>
...
</Appenders>
Полный пример с файловым приложением:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<File name="File" fileName="${filename}">
<PatternLayout>
<pattern>%d %p %C{1.} [%t] %m%n</pattern>
</PatternLayout>
</File>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="File"/>
</Root>
</Loggers>
</Configuration>
Как уже упоминалось, это просто фасад, и это помогает легко переключаться между различными версиями регистратора. Например, если вы хотите использовать реализацию log4j.
Пример кода будет выглядеть ниже.
Если вы используете maven, получите зависимости
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.6</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.5</version>
</dependency>
Have ниже в log4j.properties в местоположении src / main / resources / log4j.properties
log4j.rootLogger=DEBUG, STDOUT, file
log4j.appender.STDOUT=org.apache.log4j.ConsoleAppender
log4j.appender.STDOUT.layout=org.apache.log4j.PatternLayout
log4j.appender.STDOUT.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=mylogs.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{dd-MM-yyyy HH:mm:ss} %-5p %c{1}:%L - %m%n
Привет, приведенный ниже код мира будет выводиться на консоль и в файл журнала в соответствии с приведенной выше конфигурацией.
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HelloWorld {
public static void main(String[] args) {
Logger logger = LoggerFactory.getLogger(HelloWorld.class);
logger.info("Hello World");
}
}
[/g0]
По умолчанию файл не записывается в файл. Вам нужно будет настроить что-то вроде RollingFileAppender
и записать в него корневой журнал (возможно, в дополнение к по умолчанию ConsoleAppender
).
Файл журнала не отображается, поскольку местоположение файла конфигурации slf4j необходимо передать в команду запуска java, используя следующие аргументы. (например)
-Dlogging.config = {file_location} \ log4j2.xml
-Dlog4j.configurationFile = {file_location} \ log4j2.xml