'분류 전체보기'에 해당되는 글 56건
- 2018.07.11
- 2018.07.06
- 2018.07.05
- 2018.07.05
- 2018.07.05
응용 시스템에서 로그를 남기기 위해 Logback을 사용하는 경우 Properties를 별도의 파일로 분리하여 설정이 가능하다.
■ logback.properties
####################################################### # Logback propertiies # ####################################################### log.dir=d:/temp/logs/batchagent log.level=DEBUG app.log.name=agent_app err.log.name=agent_error max.history=7 max.log.file.size=50MB |
Properties 파일은 key=value로 정의하면 된다.
■ logback.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE xml> <configuration scan="true" scanPeriod="60 seconds"> <property file="${user.dir}/conf/logback.properties" /> <!-- Application Log Appender --> <appender name="applog" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${log.dir}/${app.log.name}.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${log.dir}/%d{yyyy-MM, aux}/${app.log.name}.%d{yyyy-MM-dd}.%i.log.zip</fileNamePattern> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>${max.log.file.size}</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> <maxHistory>${max.history}</maxHistory> </rollingPolicy> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <charset>UTF-8</charset> <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{50}.%M\(%line\) | %msg%n</pattern> </encoder> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>${log.level}</level> </filter> </appender> <!-- Error Log Appender --> <appender name="errorlog" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${log.dir}/${err.log.name}.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${log.dir}/%d{yyyy-MM, aux}/${err.log.name}.%d{yyyy-MM-dd}.%i.log.zip</fileNamePattern> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>${max.log.file.size}</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> <maxHistory>${max.history}</maxHistory> </rollingPolicy> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <charset>UTF-8</charset> <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{50}.%M\(%line\) | %msg%n</pattern> </encoder> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>WARN</level> </filter> </appender>
<!-- SQL Log Appender --> <appender name="sqllog" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_DIR}/${SQL_LOG}.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${log.dir}/%d{yyyy-MM, aux}/${sql.log.name}.%d{yyyy-MM-dd}.%i.log.zip</fileNamePattern> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>${max.log.file.size}</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> <maxHistory>${max.history}</maxHistory> </rollingPolicy> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <charset>UTF-8</charset> <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{50}.%M\(%line\) | %msg%n</pattern> </encoder> </appender>
<!-- End log appender --> <logger name="org.springframework" level="${log.level}" additivity="false"> <appender-ref ref="applog" /> <appender-ref ref="errorlog" /> </logger> <logger name="org.springframework.jdbc" additivity="false"> <level value="WARN" /> <appender-ref ref="errorlog" /> </logger> <logger name="org.mybatis.spring" level="${log.level}" additivity="false"> <appender-ref ref="applog" /> <appender-ref ref="errorlog" /> </logger> <logger name="io.netty" level="${log.level}" additivity="false"> <appender-ref ref="applog" /> <appender-ref ref="errorlog" /> </logger>
<logger name="org.apache.http" level="${log.level}" additivity="false"> <appender-ref ref="applog" /> <appender-ref ref="errorlog" /> </logger> <logger name="org.apache.ibatis" level="${log.level}" additivity="false"> <appender-ref ref="applog" /> <appender-ref ref="errorlog" /> </logger> <logger name="org.quartz" level="${log.level}" additivity="false"> <appender-ref ref="applog" /> <appender-ref ref="errorlog" /> </logger> <!-- SQL base level --> <logger name="java.sql" additivity="false"> <level value="WARN" /> <appender-ref ref="errorlog" /> </logger> <!--JDBC SQL Query Print logging level--> <logger name="jdbc.connection" level="OFF" additivity="false"> <appender-ref ref="errorlog" /> </logger> <logger name="jdbc.resultset" level="OFF" additivity="false"> <appender-ref ref="errorlog" /> </logger> <logger name="jdbc.audit" level="OFF" additivity="false"> <appender-ref ref="errorlog" /> </logger> <logger name="jdbc.sqltiming" level="OFF" additivity="false"> <appender-ref ref="sqllog" /> </logger> <!-- want to log sql result, set level info --> <logger name="jdbc.resultsettable" level="INFO" additivity="false"> <appender-ref ref="sqllog" /> </logger>
<logger name="jdbc.sqlonly" level="DEBUG" additivity="false"> <appender-ref ref="sqllog" /> </logger> <root level="${log.level}"> <appender-ref ref="console" /> <appender-ref ref="errorlog" /> </root>
</configuration> |
logback.xml 파일에 properties 파일을 <property file="" />를 이용하여 Properties 파일을 읽는다.
Properties 파일에 정의되어 있는 Property를 사용할 때 ${property key}로 사용하면 된다.
Java를 이용하여 시스템에 대한 CPU, 메모리의 정보를 받아오기 위해서 sigar Library를 이용하면 쉽고 정확하게 원하는 정보를 추출할 수 있다.
sigar는 scouter APM 툴에서 서버의 자원을 모니터링하기 위해서 사용하고 있다.
■ 소스 예제
import java.util.HashMap; import java.util.Map; import org.hyperic.sigar.CpuPerc; import org.hyperic.sigar.DirStat; import org.hyperic.sigar.DiskUsage; import org.hyperic.sigar.FileSystem; import org.hyperic.sigar.FileSystemUsage; import org.hyperic.sigar.Mem; import org.hyperic.sigar.NetFlags; import org.hyperic.sigar.NetInterfaceConfig; import org.hyperic.sigar.NetInterfaceStat; import org.hyperic.sigar.Sigar; import org.hyperic.sigar.SigarProxy; import org.hyperic.sigar.SigarProxyCache; import org.hyperic.sigar.Swap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class HostPerf { private static final Logger LOGGER = LoggerFactory.getLogger(HostPerf.class); static int SLEEP_TIME = 2000; static Sigar sigarImpl = new Sigar(); static SigarProxy sigar = SigarProxyCache.newInstance(sigarImpl, SLEEP_TIME); public static Map<String, Float> getCpuUsage() throws Exception { Map<String, Float> cpuInfo = new HashMap<String, Float>(); CpuPerc cpuPerc = sigar.getCpuPerc(); float idle = (float) cpuPerc.getIdle(); float cpu = (float) ((1.0D - idle) * 100.0D); float sysCpu = (float) cpuPerc.getSys() * 100.0F; float userCpu = (float) cpuPerc.getUser() * 100.0F; cpuInfo.put("cpuUsed", cpu); cpuInfo.put("cpuFree", idle); cpuInfo.put("sysCpu", sysCpu); cpuInfo.put("userCpu", userCpu); return cpuInfo; } public static Map<String, Float> getMemInfo() throws Exception { Map<String, Float> memInfo = new HashMap<String, Float>(); Mem m = sigar.getMem(); float tmem = m.getTotal(); float fmem = m.getActualFree(); float umem = m.getActualUsed(); float memrate = (float) m.getUsedPercent(); memInfo.put("memTotal", tmem); memInfo.put("memFree", fmem); memInfo.put("memUsed", umem); memInfo.put("memRate", memrate); Swap sw = sigar.getSwap(); float pagein = sw.getPageIn(); float pageout = sw.getPageOut(); float tswap = sw.getTotal(); float uswap = sw.getUsed(); float swaprate = tswap == 0L ? 0.0F : (float) uswap * 100.0F / (float) tswap; memInfo.put("pageIn", pagein); memInfo.put("pageOut", pageout); memInfo.put("swapTotal", tswap); memInfo.put("swapUsed", uswap); memInfo.put("swapRate", swaprate); return memInfo; } } |
소스코드를 수행하면 다음과 같은 오류메세지가 발생한다.
■ 오류
no sigar-amd64-winnt.dll in java.library.path org.hyperic.sigar.SigarException: no sigar-amd64-winnt.dll in java.library.path |
위의 오류를 해결하기 위해 sigar에서 제공하는 OS 환경에 맞는 Library를 설정해야한다.
먼저 hyperic-sigar-1.6.4.zip를 다운로드하여 압축을 해제한 후 Runtime 환경에 맞는 Library를 디렉토리에 Copy 한다.
프로그램을 실행할 때 JVM 파라미터로 -Djava.library.path=Library Directory 입력한 후 프로그램을 실행한다.
■ 실행결과
{cpuFree=0.92296225, cpuUsed=7.7037754, userCpu=1.4910537, sysCpu=5.417495} {memFree=6.194135E8, swapUsed=6.4725484E9, memTotal=4.19631923E9, swapTotal=8.3907338E9, pageIn=2.0350976E8, memUsed=3.57690573E9, pageOut=1691194.0, swapRate=77.139244, memRate=85.23912} |
일반적인 Java project를 빌드하여 개발환경에 배포하는 Ant Script이다.
■ Ant script 예제
<?xml version="1.0" encoding="UTF-8"?> <project name="portal" default="default" basedir="."> <!-- CI Informaton for build --> <property name="ci.home" value="/engn001/ciserv" /> <property name="ci.job.home" value="${ci.home}/hudson/jobs" /> <property name="ci.app.home" value="${ci.job.home}/HUDSON-JOB-NAME/workspace" /> <-- Project informamtion --> <property name="app.name" value="xxxx" /> <property name="java.encoding" value="UTF-8" /> <property name="src.dir" value="src/main/java" /> <!-- Copy source to tempoary directory --> <property name="tmp.dir" value="${ci.app.home}/target/${app.name}"/> <property name="tmp.dir.classes" value="${tmp.dir}/WEB-INF/classes"/> <property name="lib.dir" value="${tmp.dir}/WEB-INF/lib"/>
<!-- Server information for development --> <property name="was.ip" value=""/> <property name="was.port" value="" /> <property name="was.userid" value="" /> <property name="keyfile.dir" value="" /> <property name="was.home" value="/engn001/apache-tomcat-7.0.76" /> <property name="ci.war.dir" value="/engn001/ciserv/hudson/jobs/HUDSON-JOB-NAME/workspace" /> <property name="war.filename" value="portal.war" />
<!-- Source directory for development --> <property name="was.tmp.src.dir" value="" /> <property name="was.src.dir" value="" />
<!-- =============================================================== --> <!-- Build source to war --> <!-- =============================================================== --> <path id="classpath"> <fileset dir="${lib.dir}" includes="**/*.jar"/> <fileset dir="/engn001/ciserv/lib/tomcat7" includes="**/*.jar"/> </path> <!-- Start Build --> <target name="default" depends="init, prepare, compile, war, stop-tomcat, copy-war, unzip-war, start-tomcat"/>
<!-- Tempoary directory delete and create --> <target name="init"> <delete dir="${tmp.dir.classes}"/> <mkdir dir="${tmp.dir}" /> <mkdir dir="${tmp.dir.classes}" /> </target> <!-- Synchronize source to tempoary directory --> <target name="prepare" depends="init"> <sync todir="${tmp.dir}"> <fileset dir="${src.dir.web}"/> </sync> <sync todir="${tmp.dir.classes}"> <fileset dir="${src.resources.dir}"/> </sync> </target> <!-- Source compile for portal development --> <target name="compile" depends="prepare"> <javac srcdir="${src.dir}" destdir="${tmp.dir.classes}" deprecation="off" debug="on" includeantruntime="true"> <classpath refid="classpath"/> </javac> </target> <!-- Generate war file for portal development --> <target name="war" depends="compile"> <jar jarfile="${app.name}.war"> <fileset dir="${tmp.dir}"> <include name="**/*"/> <exclude name="demo/**"/> <exclude name="help/**"/> <exclude name="report/**"/> <exclude name="resource/**"/> <exclude name="xml/**" /> </fileset> </jar> </target>
<!-- Copy war file to portal development server in /tmp/src directory--> <target name="copy-war" depends="war"> <echo message="Remote copy war file to was server "/> <exec executable="scp" dir="." failonerror="true"> <arg value="-r"/> <arg value="-i"/> <arg value="${keyfile.dir}" /> <arg value="${ci.war.dir}/${war.filename}" /> <arg value="${was.userid}@${was.ip}:${was.tmp.src.dir}"/> </exec> </target>
<!--Stop tomcat --> <target name="stop-tomcat" depends="copy-war"> <sshexec host="${was.ip}" username="${was.userid}" port="${was.port}" keyfile="${keyfile.dir}" command="sudo su -c ${was.home}/bin/shutdown.sh tomcat; cd ${was.src.dir}; sudo rm -rf *" trust="true"/> </target> <sleep seconds="10" />
<!-- Unzip war file in portal development source directory --> <target name="unzip-war" depends="stop-tomcat"> <echo message="WAS server source unzip" /> <sshexec host="${was.ip}" username="${was.userid}" keyfile="${keyfile.dir}" port="${was.port}" command="sudo cp ${was.tmp.src.dir}/${war.filename} ${was.src.dir}; cd ${was.src.dir}; sudo unzip ${was.src.dir}/${war.filename}; sudo cp ${was.src.dir}/WEB-INF/classes/svrcfg/dev/bizactor.controlling.jar ${was.src.dir}/WEB-INF/lib/bizactor.controlling.jar; sudo cp ${was.src.dir}/WEB-INF/classes/svrcfg/dev/bizactor.modeling.jar ${was.src.dir}/WEB-INF/lib/bizactor.modeling.jar; sudo rm -rf ${was.src.dir}/${app.name}.war; sudo chown -R tomcat:tomcat /logs001/ibm; sudo chown -R tomcat:tomcat *" trust="true"/>
<echo message="Web server source unzip" /> </target>
<!-- Start portal development tomcat --> <echo message="Tomcat Start" /> <target name="start-tomcat" depends="unzip-war"> <sshexec host="${was.ip}" username="${was.userid}" keyfile="${keyfile.dir}" port="${was.port}" command="cd ${was.src.dir} sudo chown -R tomcat:tomcat *; sudo su -c ${was.home}/bin/startup.sh tomcat" trust="true"/> </target>
</project> |
Java Project가 아닌 단순 Project를 생성하여 ZIP으로 압축한 후 배포 서버로 생성된 ZIP 파일을 전송한 후 압축을 해제하는 Ant Build Script이다.
■ Project ZIP Ant build script
<?xml version="1.0" encoding="UTF-8"?> <!-- To change this license header, choose License Headers in Project Properties. To change this template file, choose Tools | Templates and open the template in the editor. --> <project name="sehati-oz" default="main" basedir="."> <description> Description of your project </description>
<property name="ci.home" value="/engn001/ciserv" /> <property name="ci.job.home" value="${ci.home}/hudson/jobs" /> <property name="ci.app.home" value="${ci.job.home}/SEHATI-OZ-DEV/workspace" />
<property name="projectName" value="xxxx-oz" />
<!-- OZ sources --> <property name="oz.dir" location="oz" />
<property name="target.dir" value="${ci.app.home}/target" />
<property name="portal.ip" value=""/> <property name="ibm.ip" value="" /> <property name="was.port" value="" /> <property name="was.userid" value="" /> <property name="keyfile.dir" value="" /> <property name="was.tmp.src.dir" value="/tmp/src" />
<property name="aaa.oz.target" value="" /> <property name="bbb.oz.target" value="" />
<target name="main" depends="clean, init, zip, unzip, systemzip, deleteDir, copyTarget, unzip-oz" /> <target name="clean" description="Flush staging directory"> <delete dir="${staging.dir}" failonerror="false"/> </target> <target name="init"> <mkdir dir="${target.dir}" /> </target>
<target name="zip" depends="clean" description="package, output to ZIP"> <zip destfile="${target.dir}/${projectName}.zip" basedir="${oz.dir}" /> </target> <target name="unzip" depends="zip" description="package, output to UNZIP"> <unzip src="${target.dir}/${projectName}.zip" dest="${target.dir}" /> </target>
<!-- zip file according to system --> <target name="systemzip" depends="unzip" description="package, output to ZIP"> <zip destfile="${target.dir}/${projectName}_IBM.zip" basedir="${target.dir}/IBM" /> <zip destfile="${target.dir}/${projectName}_PORTAL.zip" basedir="${target.dir}/PORTAL" /> </target>
<!-- CI Oz unzip dir delete --> <target name="deleteDir" depends="unzip" description="package, output to ZIP"> <delete dir="${target.dir}/IBM" /> <delete dir="${target.dir}/PORTAL" /> </target>
<!--Copy to IBM, Porta WAS --> <target name="copyTarget" depends="deleteDir" description="package, output to ZIP"> <exec executable="scp" dir="." failonerror="true"> <arg value="-r"/> <arg value="-i"/> <arg value="${keyfile.dir}" /> <arg value="${target.dir}/${projectName}_IBM.zip" /> <arg value="${was.userid}@${ibm.ip}:${was.tmp.src.dir}"/> </exec> <exec executable="scp" dir="." failonerror="true"> <arg value="-r"/> <arg value="-i"/> <arg value="${keyfile.dir}" /> <arg value="${target.dir}/${projectName}_PORTAL.zip" /> <arg value="${was.userid}@${portal.ip}:${was.tmp.src.dir}"/> </exec> </target>
<!--unzip --> <target name="unzip-oz" depends="copyTarget"> <sshexec host="${ibm.ip}" username="${was.userid}" keyfile="${keyfile.dir}" port="${was.port}" command="sudo cp ${was.tmp.src.dir}/${projectName}_IBM.zip ${ibm.oz.target}; cd ${ibm.oz.target}; sudo unzip -o ${projectName}_IBM.zip; sudo rm -rf ${projectName}_IBM.zip; sudo chown tomcat:tomcat ${ibm.oz.target}" trust="true"/> <sshexec host="${portal.ip}" username="${was.userid}" keyfile="${keyfile.dir}" port="${was.port}" command="sudo cp ${was.tmp.src.dir}/${projectName}_PORTAL.zip ${portal.oz.target}; cd ${portal.oz.target}; sudo unzip -o ${projectName}_PORTAL.zip; sudo rm -rf ${projectName}_PORTAL.zip; sudo chown tomcat:tomcat ${portal.oz.target}" trust="true"/> </target>
</project> |
Java에서 Shell 호출 시 apache commons-exec를 사용하면 쉽게 shell을 호출하고 shell에 파라미터 전달도 가능하다.
import java.io.ByteArrayOutputStream; import java.util.HashMap; import java.util.Map; import org.apache.commons.exec.CommandLine; import org.apache.commons.exec.DefaultExecuteResultHandler; import org.apache.commons.exec.DefaultExecutor; import org.apache.commons.exec.ExecuteStreamHandler; import org.apache.commons.exec.ExecuteWatchdog; import org.apache.commons.exec.PumpStreamHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.servlet.ModelAndView; import ncd.spring.common.util.PropertyUtil;
@Controller public class DeployController { private static final Logger LOGGER = LoggerFactory.getLogger(DeployController.class);
@RequestMapping(value = "/admin/deploy.do") public ModelAndView sourceDeploy(@RequestParam("type") String type) throws Exception { LOGGER.info("Start Source Deploy....");
final Map<String, Object> resultMap = new HashMap<String, Object>(); String scriptFile = PropertyUtil.getString("deploy.script.file"); String confFile = null; if ("oz".equals(type)) { confFile = PropertyUtil.getString("oz.deploy.config.file"); } else { confFile = PropertyUtil.getString("was.deploy.config.file"); } if (scriptFile == null || confFile == null) { resultMap.put("error", "script file or config file is null"); return new ModelAndView("ajaxMultiDataView", resultMap); }
LOGGER.info("{},{}", scriptFile, confFile);
/** Initiate Executor **/ DefaultExecutor executor = new DefaultExecutor(); ExecuteWatchdog watchDog = new ExecuteWatchdog(60*1000); executor.setWatchdog(watchDog); DefaultExecuteResultHandler resultHandler = new DefaultExecuteResultHandler(); ByteArrayOutputStream bos = new ByteArrayOutputStream(); ExecuteStreamHandler stream = new PumpStreamHandler(bos, bos, null); executor.setStreamHandler(stream);
/** Initiate Command Line **/ CommandLine cmdLine = new CommandLine(PropertyUtil.getString("deploy.script.command"));
/** Set parameter to command line **/ cmdLine.addArgument(scriptFile); cmdLine.addArgument(confFile); cmdLine.addArgument(type);
LOGGER.info("Execute Command :: ", cmdLine.toString());
/** Execute shell **/ try { executor.execute(cmdLine, resultHandler); resultHandler.waitFor(); int exitCode = resultHandler.getExitValue(); String result = bos.toString(); LOGGER.info("Result :: ", result); resultMap.put("result", result); resultMap.put("exitCode", exitCode); } catch(Exception ex) { LOGGER.error(ex.getMessage()); } finally { bos.close(); } ModelAndView mav = new ModelAndView("ajaxMultiDataView", resultMap); return mav; } |
Java Convert Map to XML 예제 (0) | 2018.07.26 |
---|---|
JVM GC 설정 (0) | 2018.06.07 |
Java Reflection 사용법 (0) | 2018.04.12 |
JSP의 img, script에 jsessionid가 추가되는 경우 (0) | 2018.02.22 |
Html a tag function call (0) | 2018.02.20 |