Archive for 6월, 2017

무심코 지나칠 수 있는 전원버튼의 숨겨진 비밀 : 네이버 포스트

2017/06/30

무심코 지나칠 수 있는 전원버튼의 숨겨진 비밀 : 네이버 포스트

http://m.post.naver.com/viewer/postView.nhn?volumeNo=8352007&memberNo=12179716

엔지니어를 위한 파이썬 및 기술 블로그: Vagrant 15분만에 윈도우에서 Ansible 테스트 환경 구축하기 (서버 1대 + 노드 5대)

2017/06/30

https://sysnet4admin.blogspot.kr/2017/06/vagrant-15-ansible-1-5.html?m=1#.WVUSsCvrcBu.facebook

나의 iPhone에서 보냄

오픈소스컨설팅, 르노삼성자동차 AWS 클라 우드로 이관 구축 – ITWorld Korea

2017/06/30

http://www.itworld.co.kr/news/105403

나의 iPhone에서 보냄

‘내 웹사이트, 잘 운영되고 있나?’ 진단해볼까

2017/06/30

—-
‘내 웹사이트, 잘 운영되고 있나?’ 진단해볼까
// Bloter.net

심리학에서 ‘초두효과’라는 현상이 있다. 처음 제시된 정보 또는 인상이 나중에 제시된 정보보다 기억에 더 큰 영향을 준다는 말이다. 첫인상은 그만큼 중요하다. 인터넷에서 웹사이트는 고객들이 만나는 기업의 첫 얼굴이다. 근데 그 첫인상이 좋지 않다면? 다시 방문하고 싶은 마음이 들지 않을 것이다. 웹사이트를 진단하기 위한 무료 도구로 좋은 첫인상을 만드는 데 한 발짝 더 다가 가보자.

모바일 웹사이트 속도를 측정해본다 – 구글 ‘테스트 마이 사이트(Test My Site)

모바일의 중요성은 두 번 말하면 입 아플 정도다. 많은 사람이 모바일로 웹사이트에 접속한다. 웹사이트 뜨는 속도가 느리면 고객들은 기다리지 않고 바로 뒤로 가기 버튼을 누른다. 심지어 모바일 사용자 46%는 검색할 때 가장 짜증스러운 경우가 페이지가 늦게 뜰 때라고 말한다.

구글은 이런 점에 개선을 돕기 위해 6월30일 모바일 웹사이트 속도를 확인할 수 있는 도구 ‘테스트 마이 사이트’를 블로그에 소개했다.

사이트 첫 페이지에 속도를 분석하고 싶은 웹페이지 주소를 넣기만 하면 된다. 최대 1분 정도의 시간을 거쳐 분석 결과를 보여준다.

가장 먼저 사이트 로딩 속도를 보여준다. 2016년 구글 더블 클릭 연구 결과에 따르면 모바일 사용자 절반 이상이 사이트가 2초 이내에 로딩되길 기대한다. 결과에서는 몇 초 만에 모바일 웹사이트가 뜨는지 보여주고, 로딩 시간 때문에 잃을 수도 있는 방문자 예상치를 퍼센트로 보여준다.

'스펙으로 보는 아이폰 10년' 포스트를 봤을 때 사이트 로드 속도를 측정해 보았다. 사이트 로드에 7초가 걸리고 사이트 로드 최적 시간이라고 여기는 3초를 기준으로 그 이상 시간이 걸릴 때 사용자 이탈률을 나타낸다.

‘스펙으로 보는 아이폰 10년’ 포스트를 봤을 때 사이트 로딩 속도를 측정해 보았다. 사이트 로딩에 7초가 걸리고 사이트 로딩 최적 시간이라고 여기는 3초를 기준으로 그 이상 시간이 걸릴 때 사용자 이탈률을 나타낸다.

다음으로 내 사이트 로딩 시간을 같은 업계 사이트와 비교해 그래프로 보여준다. 3초 이내를 ‘아주 좋음’ 기준으로 삼아 ‘우수함’, ‘양호함’, ‘저조함’으로 단계가 나뉜다. 내 사이트 업종이 바르지 않다면, 그래프 아래 버튼을 눌러 새로 지정해줄 수도 있다. 이 결과는 500만개 이상의 웹페이지를 구글 내부 연구 기반으로 생성된다.

업종 내(內) 내 사이트 로드 수준을 비교해 그래프로 보여준다.

업종에서 내 사이트 로드 수준을 비교해 그래프로 보여준다.

진단해서 문제가 있다면 해결 방법 역시 궁금할 수밖에 없다. 테스트 마이 사이트는 측정에서 끝나는 것이 아니라 무료 보고서도 제공한다. ‘무료 보고서 받기‘를 클릭하면 이용 약관 동의에 따라 사이트 속도 개선을 위한 맞춤 권장 사항 및 자세한 분석 결과를 메일로 받을 수 있다.

내 사이트는 글로벌 웹 표준에 맞게 돌아갈까? – ‘네이버 웹마스터 도구’

2014년 배타서비스를 시작한 ‘네이버 웹마스터 도구‘는 웹사이트가 검색에 얼마나 최적화돼 있는지 점검하고 웹페이지의 콘텐츠들이 웹 생태계에 선순환될 수 있게 하려고 마련된 웹사이트 현황 진단 도구다. 사이트 관리 대행사를 활용하기 어려운 중소 사이트 운영자, 콘텐츠 창작자들이 무료로 쉽게 사용할 수 있다.

네이버 웹마스터 도구 '사이트 최척화' 탭

네이버 웹마스터 도구 ‘사이트 최척화’

사이트 주소를 등록하고 나면 요약, 현황, 요청, 검증 탭을 통해서 내 사이트를 관리할 수 있다.

현황 탭의 ‘사이트 최적화‘에서는 네이버 검색 로봇이 인공지능 기술을 이용해 글로벌 웹표준에 맞게 사이트를 진단한다. 웹사이트의 수집·구조·활성화 현황·콘텐츠 품질 등을 등급별로 확인할 수 있다. 글로벌 웹표준 항목에서 내 웹사이트가 놓치고 있는 부분이 무엇인지 쉽게 점검할 수 있다. 처음 사이트를 등록하면 검색 로봇이 사이트를 진단하는 데 약간의 시간이 걸린다. 검색 로봇의 접근을 제한하는 요소가 있다면 그 부분을 해결해줘야 리포트를 원활하게 받을 수 있다.

네이버 웹마스터 도구 '백링크'

네이버 웹마스터 도구 ‘콘텐츠 확산’

현황 탭의 ‘콘텐츠 확산‘에서는 내 웹사이트의 콘텐츠를 어떤 외부 사이트가 얼마나 백링크백링크(backlinks)란 타 사이트에서 내 사이트의 콘텐츠를 언급할 때 사용하는 HTML 링크를 의미한다. 콘텐츠 확산은 백링크에 대한 통계자료이며 백링크를 많이 받는다면 평판이 좋은 사이트로 판단할 수 있다. (출처 : 네이버 검색 공식 블로그)close했는지 알 수 있도록 외부 사이트 도메인 상위 리스트와 백링크된 수치를 제공한다.

네이버 웹마스터 도구 '채널 반영'

네이버 웹마스터 도구 ‘채널 반영’

‘요청’ 탭의 ‘채널 반영‘에서는 웹사이트별로 운영하는 SNS 채널을 묶을 수 있는 기능을 제공한다. 검색 로봇이 내 웹사이트와 함께 운영하는 관련 채널들이 서로 연관성이 있다는 것을 인지하고 분석할 수 있게 해 검색 수집 및 반영에 도움을 준다. 현재 네이버 블로그·카페·포스트, 스토어팜, 폴라, 인스타그램, 아이튠즈, 구글 플레이 스토어를 지원한다. 최대 9개의 채널까지 연동할 수 있다.

이 밖에도 올해 하반기, 네이버 웹마스터 도구는 본인이 운영하는 웹사이트의 주제에 따라 검색 결과 형태가 변경 및 노출되도록 설정돼 있는지 조회하고 검증할 수 있는 기능도 준비하고 있다.

—-

Read in my feedly

나의 iPhone에서 보냄

신문보기 :: 네이버 뉴스

2017/06/30

http://m.news.naver.com/newspaper/read.nhn?date=&aid=0002370222&oid=028

나의 iPhone에서 보냄

Introduction to Netflix Servo

2017/06/29

—-
Introduction to Netflix Servo
// Baeldung

1. Overview

Netflix Servo is a metrics tool for Java applications. Servo is similar to Dropwizard Metrics, yet much simpler. It leverages JMX only to provide a simple interface for exposing and publishing application metrics.

In this article, we’ll introduce what Servo provides and how can we use it to collect and publish application metrics.

2. Maven Dependencies

Before we dive into actual implementation, let’s add the Servo dependency to the pom.xml file:

<dependency> <groupId>com.netflix.servo</groupId> <artifactId>servo-core</artifactId> <version>0.12.16</version> </dependency>

Besides, there are many extensions available, such as Servo-Apache, Servo-AWS, etc. We may need them later. Latest versions of these extensions can also be found on Maven Central.

3. Collect Metrics

First, let’s see how to gather metrics from our application.

Servo provides four primary metric types: Counter, Gauge, Timer, and Informational.

3.1. Metric Types – Counter

Counters are used to record incrementation. Commonly used implementations are BasicCounter, StepCounter, and PeakRateCounter.

BasicCounter does what a counter should do, plain and straightforward:

Counter counter = new BasicCounter(MonitorConfig.builder("test").build()); assertEquals("counter should start with 0", 0, counter.getValue().intValue()); counter.increment(); assertEquals("counter should have increased by 1", 1, counter.getValue().intValue()); counter.increment(-1); assertEquals("counter should have decreased by 1", 0, counter.getValue().intValue());

PeakRateCounter returns the maximum count for a given second during the polling interval:

Counter counter = new PeakRateCounter(MonitorConfig.builder("test").build()); assertEquals( "counter should start with 0", 0, counter.getValue().intValue()); counter.increment(); SECONDS.sleep(1); counter.increment(); counter.increment(); assertEquals("peak rate should have be 2", 2, counter.getValue().intValue());

Unlike other counters, StepCounter records rate per second of previous polling interval:

System.setProperty("servo.pollers", "1000"); Counter counter = new StepCounter(MonitorConfig.builder("test").build()); assertEquals("counter should start with rate 0.0", 0.0, counter.getValue()); counter.increment(); SECONDS.sleep(1); assertEquals( "counter rate should have increased to 1.0", 1.0, counter.getValue());

Notice that we set the servo.pollers to 1000 in the code above. That was to set the polling interval to 1 second instead of intervals of 60 seconds and 10 seconds by default. We’ll cover more on this later.

3.2. Metric Types – Gauge

Gauge is a simple monitor that returns the current value. BasicGauge, MinGauge, MaxGauge, and NumberGauges are provided.

BasicGauge invokes a Callable to get the current value. We can get the size of a collection, latest value of a BlockingQueue or any value that requires small computations.

Gauge<Double> gauge = new BasicGauge<>(MonitorConfig.builder("test") .build(), () -> 2.32); assertEquals(2.32, gauge.getValue(), 0.01);

MaxGauge and MinGauge are used to keep track of the maximum and minimum values respectively:

MaxGauge gauge = new MaxGauge(MonitorConfig.builder("test").build()); assertEquals(0, gauge.getValue().intValue()); gauge.update(4); assertEquals(4, gauge.getCurrentValue(0)); gauge.update(1); assertEquals(4, gauge.getCurrentValue(0));

NumberGauge (LongGauge, DoubleGauge) wraps a provided Number (Long, Double). To collect metrics using these gauges, we must ensure the Number is thread-safe.

3.3. Metric Types – Timer

Timers help measure duration of a particular event. Default implementations are BasicTimer, StatsTimer, and BucketTimer.

BasicTimer records total time, count and other simple statistics:

BasicTimer timer = new BasicTimer(MonitorConfig.builder("test").build(), SECONDS); Stopwatch stopwatch = timer.start(); SECONDS.sleep(1); timer.record(2, SECONDS); stopwatch.stop(); assertEquals("timer should count 1 second", 1, timer.getValue().intValue()); assertEquals("timer should count 3 seconds in total", 3.0, timer.getTotalTime(), 0.01); assertEquals("timer should record 2 updates", 2, timer.getCount().intValue()); assertEquals("timer should have max 2", 2, timer.getMax(), 0.01);

StatsTimer provides much richer statistics by sampling between polling intervals:

System.setProperty("netflix.servo", "1000"); StatsTimer timer = new StatsTimer(MonitorConfig .builder("test") .build(), new StatsConfig.Builder() .withComputeFrequencyMillis(2000) .withPercentiles(new double[] { 99.0, 95.0, 90.0 }) .withPublishMax(true) .withPublishMin(true) .withPublishCount(true) .withPublishMean(true) .withPublishStdDev(true) .withPublishVariance(true) .build(), SECONDS); Stopwatch stopwatch = timer.start(); SECONDS.sleep(1); timer.record(3, SECONDS); stopwatch.stop(); stopwatch = timer.start(); timer.record(6, SECONDS); SECONDS.sleep(2); stopwatch.stop(); assertEquals("timer should count 12 seconds in total", 12, timer.getTotalTime()); assertEquals("timer should count 12 seconds in total", 12, timer.getTotalMeasurement()); assertEquals("timer should record 4 updates", 4, timer.getCount()); assertEquals("stats timer value time-cost/update should be 2", 3, timer.getValue().intValue()); final Map<String, Number> metricMap = timer.getMonitors().stream() .collect(toMap(monitor -> getMonitorTagValue(monitor, "statistic"), monitor -> (Number) monitor.getValue())); assertThat(metricMap.keySet(), containsInAnyOrder( "count", "totalTime", "max", "min", "variance", "stdDev", "avg", "percentile_99", "percentile_95", "percentile_90"));

BucketTimer provides a way to get the distribution of samples by bucketing value ranges:

BucketTimer timer = new BucketTimer(MonitorConfig .builder("test") .build(), new BucketConfig.Builder() .withBuckets(new long[] { 2L, 5L }) .withTimeUnit(SECONDS) .build(), SECONDS); timer.record(3); timer.record(6); assertEquals( "timer should count 9 seconds in total", 9, timer.getTotalTime().intValue()); Map<String, Long> metricMap = timer.getMonitors().stream() .filter(monitor -> monitor.getConfig().getTags().containsKey("servo.bucket")) .collect(toMap( m -> getMonitorTagValue(m, "servo.bucket"), m -> (Long) m.getValue())); assertThat(metricMap, allOf(hasEntry("bucket=2s", 0L), hasEntry("bucket=5s", 1L), hasEntry("bucket=overflow", 1L)));

To track long-time operations that might last for hours, we can use the composite monitor DurationTimer.

3.4. Metric Types – Informational

Also, we can make use of the Informational monitor to record descriptive information to help debugging and diagnostics. The only implementation is BasicInformational, and its usage cannot be simpler:

BasicInformational informational = new BasicInformational( MonitorConfig.builder("test").build()); informational.setValue("information collected");

3.5. MonitorRegistry

The metric types are all of type Monitor, which is the very base of Servo. We now know kinds of tools collect raw metrics, but to report the data, we need to register these monitors.

Note that each single configured monitor should be registered once and only once to ensure the correctness of metrics. So we can register the monitors using Singleton pattern.

Most of the time, we can use DefaultMonitorRegistry to register monitors:

Gauge<Double> gauge = new BasicGauge<>(MonitorConfig.builder("test") .build(), () -> 2.32); DefaultMonitorRegistry.getInstance().register(gauge);

If we want to dynamically register a monitor, DynamicTimer, and DynamicCounter can be used:

DynamicCounter.increment("monitor-name", "tag-key", "tag-value");

Note that dynamic registration would cause expensive lookup operation each time the value is updated.

Servo also provides several helper methods to register monitors declared in objects:

Monitors.registerObject("testObject", this); assertTrue(Monitors.isObjectRegistered("testObject", this));

Method registerObject will use reflection to add all instances of Monitors declared by annotation @Monitor and add tags declared by @MonitorTags:

@Monitor( name = "integerCounter", type = DataSourceType.COUNTER, description = "Total number of update operations.") private AtomicInteger updateCount = new AtomicInteger(0); @MonitorTags private TagList tags = new BasicTagList( newArrayList(new BasicTag("tag-key", "tag-value"))); @Test public void givenAnnotatedMonitor_whenUpdated_thenDataCollected() throws Exception { System.setProperty("servo.pollers", "1000"); Monitors.registerObject("testObject", this); assertTrue(Monitors.isObjectRegistered("testObject", this)); updateCount.incrementAndGet(); updateCount.incrementAndGet(); SECONDS.sleep(1); List<List<Metric>> metrics = observer.getObservations(); assertThat(metrics, hasSize(greaterThanOrEqualTo(1))); Iterator<List<Metric>> metricIterator = metrics.iterator(); metricIterator.next(); //skip first empty observation while (metricIterator.hasNext()) { assertThat(metricIterator.next(), hasItem( hasProperty("config", hasProperty("name", is("integerCounter"))))); } }

4. Publish Metrics

With the metrics collected, we can publish it to in any format, such as rendering time series graphs on various data visualization platforms. To publish the metrics, we need to poll the data periodically from the monitor observations.

4.1. MetricPoller

MetricPoller is used as a metrics fetcher. We can fetch metrics of MonitorRegistries, JVM, JMX. With the help of extensions, we can poll metrics like Apache server status and Tomcat metrics.

MemoryMetricObserver observer = new MemoryMetricObserver(); PollRunnable pollRunnable = new PollRunnable(new JvmMetricPoller(), new BasicMetricFilter(true), observer); PollScheduler.getInstance().start(); PollScheduler.getInstance().addPoller(pollRunnable, 1, SECONDS); SECONDS.sleep(1); PollScheduler.getInstance().stop(); List<List<Metric>> metrics = observer.getObservations(); assertThat(metrics, hasSize(greaterThanOrEqualTo(1))); List<String> keys = extractKeys(metrics); assertThat(keys, hasItems("loadedClassCount", "initUsage", "maxUsage", "threadCount"));

Here we created a JvmMetricPoller to poll metrics of JVM. When adding the poller to the scheduler, we let the poll task to run every second. System default poller configurations are defined in Pollers, but we can specify pollers to use with system property servo.pollers.

4.2. MetricObserver

When polling metrics, observations of registered MetricObservers will be updated.

MetricObservers provided by default are MemoryMetricObserver, FileMetricObserver, and AsyncMetricObserver. We have already shown how to use MemoryMetricObserver in the previous code sample.

Currently, several useful extensions are available:

We can implement a customized MetricObserver to publish application metrics to where we see fit. The only thing to care about is to handle the updated metrics:

public class CustomObserver extends BaseMetricObserver { //... @Override public void updateImpl(List<Metric> metrics) { //TODO } }

5. Summary

In this article, we have introduced how to use Netflix Servo to collect and publish application metrics.

In case you haven’t read our introduction to Dropwizard Metrics, check it out here for a quick comparison with Servo.

As always, the full implementation code of this article can be found over on Github.

—-

Read in my feedly

나의 iPhone에서 보냄

Introduction to AsciiDoctor in Java

2017/06/29

—-
Introduction to AsciiDoctor in Java
// Baeldung

1. Introduction

In this article, we’ll make a quick introduction on how to use Ascii Doctor with Java. We’ll demonstrate how to generate HTML5 or PDF from an AsciiDoc document.

2. What is AsciiDoc

AsciiDoc is a text document format. It can be used for writing documentation, books, web pages, man pages and many other.

Since it’s very configurable, AsciiDoc documents can be converted into many other formats like HTML, PDF, man pages, EPUB, and others.

Because AsciiDoc syntax is quite basic, it has become very popular with a large support in various browser plugins, plugins for programming languages and other tools.

To learn more about the tool, we suggest reading the official documentation where you can find many useful resources for learning proper syntax and methods for exporting your AsciiDoc document to other formats.

3. What is Asciidoctor

Asciidoctor is a text processor for converting AsciiDoc documents into HTML, PDF and other formats. It’s written in Ruby and packaged as a RubyGem.

As mentioned above, AsciiDoc is a very popular format for writing documentation, so you can easily find Asciidoctor as a standard package in many GNU Linux distribution like Ubuntu, Debian, Fedora, and Arch.

Since we want to use Asciidoctor on the JVM, we’ll talk about AsciidoctorJ – which is Asciidoctor with Java.

4. Dependencies

To include AsciidoctorJ package in our application, the following pom.xml entry is needed:

<dependency> <groupId>org.asciidoctor</groupId> <artifactId>asciidoctorj</artifactId> <version>1.5.5</version> </dependency> <dependency> <groupId>org.asciidoctor</groupId> <artifactId>asciidoctorj-pdf</artifactId> <version>1.5.0-alpha.15</version> </dependency>

Latest versions of libraries can be found here and here.

5. AsciidoctorJ API

The entry point for AsciidoctorJ is the Asciidoctor Java interface.

Those methods are:

  • convert – parses AsciiDoc document from a String or Stream and converts it to the provided format type
  • convertFile – parses AsciiDoc document from a provided File object and converts it to the provided format type
  • convertFiles – same as previous, but method accepts multiple File objects
  • convertDirectory – parses all AsciiDoc documents in provided folder and converts them to the provided format type

5.1. API Usage in Code

To create an Asciidoctor instance, you need to retrieve the instance from the provided factory method:

import static org.asciidoctor.Asciidoctor.Factory.create; import org.asciidoctor.Asciidoctor; .. //some code .. Asciidoctor asciidoctor = create(); 

With retrieved instance, we can convert AsciiDoc document very easily:

String output = asciidoctor .convert("Hello _Baeldung_!", new HashMap<String, Object>());

If we want to convert a text document from the file system, we’ll use the convertFile method:

String output = asciidoctor .convertFile(new File("baeldung.adoc"), new HashMap<String, Object>()); 

For converting multiple files, the convertFiles method accepts List object as a first parameter and returns arrays of String objects.
More interesting is how to convert a whole directory with AsciidoctorJ.

As mentioned above, to convert a whole directory – we should call the convertDirectory method. This scans the provided path and searches for all files with AsciiDoc extensions (.adoc, .ad, .asciidoc, .asc) and converts them. To scan all files, an instance of the DirectoryWalker should be provided to the method.

Currently, Asciidoctor provides two built-in implementations of mentioned interface:

  • AsciiDocDirectoryWalker – converts all files of given folder and its subfolders. Ignores all files starting with “_”
  • GlobDirectoryWalker – convert all files of given folder following a glob expression
String[] result = asciidoctor.convertDirectory( new AsciiDocDirectoryWalker("src/asciidoc"), new HashMap<String, Object>()); 

Also, we can call convert method with provided java.io.Reader and java.io.Writer interfaces. Reader interface is used as the source, and Writer interface is used for writing converted data:

FileReader reader = new FileReader(new File("sample.adoc")); StringWriter writer = new StringWriter(); asciidoctor.convert(reader, writer, options().asMap()); StringBuffer htmlBuffer = writer.getBuffer();

5.2. PDF Generation

To generate a PDF file from an Asciidoc document, we need to specify the type of the generated file in options. If you look a little more carefully into the previous examples, you’ll notice that second parameter of any convert method is a Map – which represents options object.

We’ll set the in_place option to true so that our file is automatically generated and saved to the file system:

Map<String, Object> options = options() .inPlace(true) .backend("pdf") .asMap(); String outfile = asciidoctor.convertFile(new File("baeldung.adoc"), options);

6. Maven Plugin

In the previous section, we showed how we can generate PDF file directly with your own implementation in Java. In this section, we will show how you to generate PDF file during Maven build.

To enable PDF generation during the build, you need to add this dependency to your pom.xml:

<plugin> <groupId>org.asciidoctor</groupId> <artifactId>asciidoctor-maven-plugin</artifactId> <version>1.5.5</version> <dependencies> <dependency> <groupId>org.asciidoctor</groupId> <artifactId>asciidoctorj-pdf</artifactId> <version>1.5.0-alpha.15</version> </dependency> </dependencies> </plugin>

The latest version of Maven plugin dependency can be found here.

6.1. Usage

To use the plugin in the build, you have to define it in the pom.xml:

<plugin> <executions> <execution> <id>output-html</id> <phase>generate-resources</phase> <goals> <goal>process-asciidoc</goal> </goals> </execution> </executions> </plugin>

Since the plugin doesn’t run in any specific phase, you have to set the phase where you want to start it.

As with the Asciidoctorj plugin, we can use various options for PDF generation here as well.

Let’s have a quick look at the basic options while you can find other options in the documentation:

  • sourceDirectory – the location of directory where you have Asciidoc documents
  • outputDirectory – the location of the directory where you want to store generated PDF files
  • backend – the type of the output from Asciidoctor. For PDF generation set for pdf

This is an example how to define basic options in the plugin:

<plugin> <configuration> <sourceDirectory>src/main/doc</sourceDirectory> <outputDirectory>target/docs</outputDirectory> <backend>pdf</backend> </configuration> </plugin>

After running the build, the PDF files can be found in the specified output directory.

7. Conclusion

Even though AsciiDoc is very easy to use and understand, it’s a very powerful tool for managing documentation and other documents.

In this article, we demonstrated a simple way to generate HTML and PDF files from AsciiDoc document.

The code can be found on over on GitHub.

—-

Read in my feedly

나의 iPhone에서 보냄

A Guide To Cron Expressions

2017/06/29

—-
A Guide To Cron Expressions
// Baeldung

1. Overview

Simply put, cron is a basic utility available on Unix-based systems. It enables users to schedule tasks to run periodically at a specified date/time. And, it’s naturally a great tool for automating lots of process runs which otherwise would require human intervention.

Cron runs as a daemon process – which means it only needs to be started once and it will keep running in the background. This process makes use of crontab to read the entries of the schedules and kicks off the tasks.

Over time, the cron expression format became widely adopted and can often be used in many other programs and libraries.

2. Working with Crontab

A cron schedule is a simple text file located under /var/spool/cron/crontabs on Linux systems. We cannot edit the crontab files directly; we need to access it using the crontab command.

For example, to open crontab file, you need to fire this command:

crontab -e

Each line in crontab is an entry with an expression and a command to run:

* * * * * * /usr/local/ispconfig/server/server.sh

This entry is added to run the mentioned script every single second.

3. Cron Expression

Let’s understand the cron expression; it consists of six fields:

<second> <minute> <hour> <day-of-month> <month> <day-of-week> <year> <command>

From these, <year> field is optional.

3.1. Specials Characters In Expression

  • *(all) – it is used to specify that event should happen for every time unit. For example, “*” in the <minute> field – means “for every minute”
  • ? (any) – it is utilized in the <day-of-month> and <day-of -week> fieldsto denote the arbitrary value – neglect the field value. For example, if we want to fire a script at “5th of every month” irrespective of what the day of the week falls on that date, then we specify a “?” in the <day-of-week> field
  • – (range) – it is used to determine the value range. For example, “10-11” in <hour> field means “10th and 11th hours”
  • , (values) – it is used to specify multiple values. For example, “MON, WED, FRI” in <day-of-week> field means on the days “Monday, Wednesday, and Friday”
  • / (increments) – it is used to specify the incremental values. For example, a “5/15” in the <minute> field, means at “5, 20, 35 and 50 minutes of an hour”
  • L (last) – it has different meanings when used in various fields. For example, if it’s applied in the <day-of-month> field, then it means last day of the month, i.e. “31st for January” and so on as per the calendar month. It can be used with an offset value, like “L-3“, which denotes the “third to last day of the calendar month”. In the <day-of-week>, it specifies the “last day of a week”. It can also be used with another value in <day-of-week>, like “6L“, which denotes the “last Friday”
  • W (weekday) – it is used to specify the weekday (Monday to Friday) nearest to a given day of the month. For example, if we specify “10W” in the <day-of-month> field, then it means the “weekday near to 10th of that month”. So if “10th” is a Saturday, then the job will be triggered on “9th”, and if “10th” is a Sunday, then it will trigger on “11th”. If you specify “1W” in the <day-of-month> and if “1st” is Saturday, then the job will be triggered on “3rd” which is Monday, and it will not jump back to the previous month
  • # – it is used to specify the “N-th” occurrence of a weekday of the month, for example, “3rd Friday of the month” can be indicated as “6#3

3.2. Cron Expression Examples

Let us see some examples of cron expression by using the fields and specials characters combinations:

At 12:00 pm (noon) every day during the year 2017:

0 0 12 * * ? 2017

Every 5 minutes starting at 1 pm and ending on 1:55 pm and then starting at 6 pm and ending at 6:55 pm, every day:

0 0/5 13,18 * * ?

Every minute starting at 1 pm and ending on 1:05 pm, every day:

0 0-5 13 * * ?

At 1:15 pm and 1:45 pm every Tuesday in the month of June:

0 15,45 13 ? 6 Tue

At 9:30 am every Monday, Tuesday, Wednesday, Thursday, and Friday:

0 30 9 ? * MON-FRI

At 9:30 am on 15th day of every month:

0 30 9 15 * ?

At 6 pm on the last day of every month:

0 0 18 L * ?

At 6 pm on the 3rd to last day of every month:

0 0 18 L-3 * ?

At 10:30 am on the last Thursday of every month:

0 30 10 ? * 5L

At 6 pm on the last Friday of every month during the years 2015, 2016 and 2017:

0 0 18 ? * 6L 2015-2017

At 10 am on the third Monday of every month:

0 0 10 ? * 2#3

At 12 am midnight on every day for five days starting on the 10th day of the month:

0 0 0 10/5 * ?

4. Cron Special Strings

In addition to the fields specified in the cron expression, there’s also support for some special, pre-defined values – which can be used instead of the fields:

  • @reboot – run once at the start-up
  • @yearly or @annualy – run once a year
  • @monthly – run once a month
  • @weekly – run once a week
  • @daily or @midnight – run once a day
  • @hourly – run hourly

5. Conclusion

In this quick article, we’ve explored about the cron jobs and crontab.

We have also seen a number of expression examples you can use in your daily work, or simply infer other expressions from.

—-

Read in my feedly

나의 iPhone에서 보냄

트위터에서 Julia Evans 님의 트윗

2017/06/28
iZAxk4qr_normal.jpg Julia Evans (@b0rk)
2017. 3. 27. 오후 12:35
bash tips (attached blog post: jvns.ca/blog/2017/03/2…) pic.twitter.com/S1lpNsjADI

트위터 앱 다운로드

나의 iPhone에서 보냄

Bash scripting quirks & safety tips – Julia Evans

2017/06/28

http://jvns.ca/blog/2017/03/26/bash-quirks/

나의 iPhone에서 보냄